学习Java第70天,过滤器Filter简介

过滤器概述

Filter,即过滤器,是JAVAEE技术规范之一,作用目标资源的请求进行过滤的一套技术规范,是Java Web项目中最为实用的技术之一

  • Filter接口定义了过滤器的开发规范,所有的过滤器都要实现该接口

  • Filter的工作位置是项目中所有目标资源之前,容器在创建HttpServletRequest和HttpServletResponse对象后,会先调用Filter的doFilter方法

  • Filter的doFilter方法可以控制请求是否继续,如果放行,则请求继续,如果拒绝,则请求到此为止,由过滤器本身做出响应

  • Filter不仅可以对请求做出过滤,也可以在目标资源做出响应前,对响应再次进行处理

  • Filter是GOF中责任链模式的典型案例

  • Filter的常用应用包括但不限于: 登录权限检查,解决网站乱码,过滤敏感字符,日志记录,性能分析... ...

生活举例: 公司前台,停车场安保,地铁验票闸机

  • 公司前台对来访人员进行审核,如果是游客则拒绝进入公司,如果是客户则放行 . 客户离开时提醒客户不要遗忘物品

  • 停车场保安对来访车辆进行控制,如果没有车位拒绝进入,如果有车位,发放停车卡并放行,车辆离开时收取请车费

  • 地铁验票闸机在人员进入之前检查票,没票拒绝进入,有票验票后放行,人员离开时同样验票

过滤器开发中应用的场景

  • 日志的记录

  • 性能的分析

  • 乱码的处理

  • 事务的控制

  • 登录的控制

  • 跨域的处理

  • ... ...

过滤器工作位置图解

 

 Filter接口API


import java.io.IOException;

public interface Filter {
    default public void init(FilterConfig filterConfig) throws ServletException {
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException;
    default public void destroy() {
    }
}

 

  • API目标

API目标
default public void init(FilterConfig filterConfig)初始化方法,由容器调用并传入初始配置信息filterConfig对象
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)过滤方法,核心方法,过滤请求,决定是否放行,响应之前的其他处理等都在该方法中
default public void destroy()销毁方法,容器在回收过滤器对象之前调用的方法

过滤器使用

目标:开发一个日志记录过滤器

  • 用户请求到达目标资源之前,记录用户的请求资源路径

  • 响应之前记录本次请求目标资源运算的耗时

  • 可以选择将日志记录进入文件,为了方便测试,这里将日志直接在控制台打印

定义一个过滤器类,编写功能代码

package com.atguigu.filters;


import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class LoggingFilter  implements Filter {

    private SimpleDateFormat dateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 参数父转子
        HttpServletRequest request =(HttpServletRequest)  servletRequest;
        HttpServletResponse  response =(HttpServletResponse)  servletResponse;
        // 拼接日志文本
        String requestURI = request.getRequestURI();
        String time = dateFormat.format(new Date());
        String beforeLogging =requestURI+"在"+time+"被请求了";
        // 打印日志
        System.out.println(beforeLogging);
        // 获取系统时间
        long t1 = System.currentTimeMillis();
        // 放行请求
        filterChain.doFilter(request,response);
        // 获取系统时间
        long t2 = System.currentTimeMillis();
        //  拼接日志文本
        String afterLogging =requestURI+"在"+time+"的请求耗时:"+(t2-t1)+"毫秒";
        // 打印日志
        System.out.println(afterLogging);

    }
}

 

  • 说明

    • doFilter方法中的请求和响应对象是以父接口的形式声明的,实际传入的实参就是HttpServletRequest和HttpServletResponse子接口级别的,可以安全强转

    • filterChain.doFilter(request,response); 这行代码的功能是放行请求,如果没有这一行代码,则请求到此为止

    • filterChain.doFilter(request,response);在放行时需要传入request和response,意味着请求和响应对象要继续传递给后续的资源,这里没有产生新的request和response对象

定义两个Servlet作为目标资源

@WebServlet(urlPatterns = "/servletA",name = "servletAName")
public class ServletA extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 处理器请求
        System.out.println("servletA处理请求的方法,耗时10毫秒");
        // 模拟处理请求耗时
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

    }
}

 

@WebServlet(urlPatterns = "/servletB", name = "servletBName")
public class ServletB extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 处理器请求
        System.out.println("servletB处理请求的方法,耗时15毫秒");
        // 模拟处理请求耗时
        try {
            Thread.sleep(15);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

配置过滤器以及过滤器的过滤范围

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">

    <!--配置filter,并为filter起别名-->
   <filter>
       <filter-name>loggingFilter</filter-name>
       <filter-class>com.atguigu.filters.LoggingFilter</filter-class>
   </filter>
    <!--为别名对应的filter配置要过滤的目标资源-->
    <filter-mapping>
        <filter-name>loggingFilter</filter-name>
        <!--通过映射路径确定过滤资源-->
        <url-pattern>/servletA</url-pattern>
        <!--通过后缀名确定过滤资源-->
        <url-pattern>*.html</url-pattern>
        <!--通过servlet别名确定过滤资源-->
        <servlet-name>servletBName</servlet-name>

    </filter-mapping>
</web-app>

说明

  • filter-mapping标签中定义了过滤器对那些资源进行过滤

  • 子标签url-pattern通过映射路径确定过滤范围

    • /servletA 精确匹配,表示对servletA资源的请求进行过滤

    • *.html 表示对以.action结尾的路径进行过滤

    • /* 表示对所有资源进行过滤

    • 一个filter-mapping下可以配置多个url-pattern

  • 子标签servlet-name通过servlet别名确定对那些servlet进行过滤

    • 使用该标签确定目标资源的前提是servlet已经起了别名

    • 一个filter-mapping下可以定义多个servlet-name

    • 一个filter-mapping下,servlet-name和url-pattern子标签可以同时存在

 

过滤器生命周期

过滤器作为web项目的组件之一,和Servlet的生命周期类似,略有不同,没有servlet的load-on-startup的配置,默认就是系统启动立刻构造

阶段对应方法执行时机执行次数
创建对象构造器web应用启动时1
初始化方法void init(FilterConfig filterConfig)构造完毕1
过滤请求void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)每次请求多次
销毁default void destroy()web应用关闭时1次

 ps:来源尚硅谷

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/247306.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity2023.3(Unity6)版本开始将可以发布WebGPU

翻译一段官网上的话&#xff1a; 利用Unity 2023.3(正式发布时应该称为Unity6)中最新的WebGPU图形API集成&#xff0c;尝试最大限度的提升您的网络游戏的真实感。 通过与谷歌的战略合作&#xff0c;Unity实时3D平台的强大的图形功能现在为图形丰富的网络游戏进行微调&#xff0…

知识库SEO:提升网站内容质量与搜索引擎排名的策略

随着搜索引擎算法的不断更新和优化&#xff0c;单纯依靠关键词堆砌和外部链接的时代已经过去。现在的SEO&#xff08;搜索引擎优化&#xff09;已经转向了以提供高质量、有价值内容为核心的阶段。知识库SEO便是这个新阶段的重要策略之一。 | 一、知识库SEO的概念与意义 1.定义…

python 新手学习 - 简单实用的 Python 周期任务调度工具

如果你想周期性地执行某个 Python 脚本&#xff0c;最出名的选择应该是 Crontab 脚本&#xff0c;但是 Crontab 具有以下缺点&#xff1a; 1.不方便执行秒级任务。 2.当需要执行的定时任务有上百个的时候&#xff0c;Crontab 的管理就会特别不方便。 还有一个选择是 Celery&a…

text-align-last: justify 使用方法,对齐字段交互

<html> <style>.label {display: inline-block;width: 100px;text-align-last: justify;} </style><body><div class"l-content"><div><div class"label">身份证&#xff1a;</div><div class"la…

DDA 算法

CAD 算法是计算机辅助设计的算法&#xff0c;几何算法是解决几何问题的算法 CAD 算法是指在计算机辅助设计软件中使用的算法&#xff0c;用于实现各种设计和绘图功能&#xff0c;CAD 广泛应用于建筑、机械、电子等领域&#xff0c;可以大大提高设计效率和精度 绘图算法是 CAD…

RLC防孤岛负载测试:电力系统安全运行的重要保障

在电力系统中&#xff0c;孤岛效应是一个严重的问题&#xff0c;它可能导致电力系统的不稳定甚至崩溃。为了确保电力系统的安全运行&#xff0c;必须进行RLC防孤岛负载测试。RLC防孤岛负载测试是一种模拟电网故障后&#xff0c;对电力系统进行检测的方法&#xff0c;主要用于检…

性格内向,如何找到适合自己的职业

很多人都会觉得性格内向是一件坏事&#xff0c;这会让自己在竞争激烈的生活中得不到好处&#xff0c;但其实在心理学上看来&#xff0c;每一种性格都有自己的优缺点&#xff0c;如果片面地用好坏去评定&#xff0c;就无法发挥性格的优势&#xff0c;也很难利用它们为自己所用。…

LLM(六)| Gemini:谷歌Gemini Pro 开放API ,Gemini Pro 可免费使用

近期&#xff0c;Google Gemini Pro 开放API 了&#xff0c;且Gemini Pro 可免费使用&#xff01;Gemini Pro支持全球180个国家的38种语言&#xff0c;目前接受文本作为输入并生成文本作为输出。 Gemini API 地址&#xff1a;http://ai.google.dev Gemini Pro 的表现超越了其他…

Linux route命令详解

1、介绍 route命令用于显示和操作IP路由表&#xff0c;它允许用户查看当前系统的路由信息&#xff0c;添加新的路由、删除已有的路由等。 2、命令 2.1 命令选项 -n, --numeric&#xff1a;不解析主机名&#xff0c;直接显示IP地址。使用这个选项可以加快显示速度&#xff0…

Git忽略已经提交的文件

原理类似于 Android修改submodule的lib包名

“唯品会API接口:电商开发者的秘密武器”

一、引言 唯品会作为一家知名的电商平台&#xff0c;提供了丰富的API接口供开发者使用。通过使用唯品会的API接口&#xff0c;开发者可以轻松地与唯品会平台进行交互&#xff0c;实现自动化处理、数据抓取等功能。本文将详细介绍唯品会API接口的使用方法、技术细节以及注意事项…

C语言->动态内存管理

系列文章目录 文章目录 前言 ✅作者简介&#xff1a;大家好&#xff0c;我是橘橙黄又青&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;橘橙黄又青_C语言,函数,指针-CSDN博客 目的&#xff1a;学习malloc&#xff0c…

【思考】只有实对称矩阵才能正交对角化吗?【矩阵的合同】

1&#xff1a;命题改写&#xff08;A可以正交对角化&#xff09; 2&#xff1a;左乘Q右乘Q逆&#xff08;Q转置&#xff09; 3&#xff1a;取转置 4&#xff1a;得证 总结 可以看到&#xff0c;矩阵如果可以正交对角化&#xff0c;那么一定是实对称矩阵。 另外&#xff0c;这…

shopee选品软件:如何利用Shopee选品软件优化你的销售业绩

在当今的电商市场中&#xff0c;选择适销的产品是成功的关键之一。然而&#xff0c;对于卖家来说&#xff0c;如何找到有潜力的产品并优化销售策略是一个具有挑战性的任务。幸运的是&#xff0c;有许多Shopee选品软件可以帮助卖家在Shopee平台上进行产品分析和选择。本文将介绍…

WPF 基于TableControl的页面切换

文章目录 前言其它项目的UserControl切换TableControl添加按钮&#xff0c;隐去TableItem的Header 结论 前言 我想用WPF简单实现一个按钮视图切换的效果&#xff0c;但是我发现别人的实现效果非常的麻烦。 其它项目的UserControl切换 我网上找了个开源的项目&#xff0c;他是…

100ask imx6ull 驱动(设备树)装载步骤

1.修改设备树文件 路径&#xff1a; vim 100ask_imx6ull-sdk/Linux-4.9.88/arch/arm/boot/dts/100ask_imx6ull-14x14.dtb 2. 回到linux内核目录下&#xff0c;执行命令 /*路径&#xff1a;100ask_imx6ull-sdk/Linux-4.9.88*/ make dtbs 将生成的arch/arm/boot/dts/100ask_…

【Spring】@SpringBootApplication注解解析

前言&#xff1a; 当我们第一次创建一个springboot工程时&#xff0c;我们会对启动类&#xff08;xxxApplication&#xff09;有许多困惑&#xff0c;为什么只要运行启动类我们在项目中自定义的bean无需配置类配置&#xff0c;扫描就能自动注入到IOC容器中&#xff1f;为什么我…

解决el-table组件中,分页后数据的勾选、回显问题?

问题描述&#xff1a; 1、记录一个弹窗点击确定按钮后&#xff0c;table列表所有勾选的数据信息2、再次打开弹窗&#xff0c;回显勾选所有保存的数据信息3、遇到的bug&#xff1a;切换分页&#xff0c;其他页面勾选的数据丢失&#xff1b;点击确认只保存当前页的数据&#xff1…

迅为RK3588开发板瑞芯微国产化工业ARM核心板AI人工智能

性能强 iTOP-3588开发板采用瑞芯微RK3588处理器&#xff0c;是全新一代AloT高端应用芯片&#xff0c;采用8nm LP制程&#xff0c;搭载八核64位CPU&#xff0c;四核Cortex-A76和四核Cortex-A55架构&#xff0c;主频高达2.4GHz&#xff0c;8GB内存&#xff0c;32GB EMMC。 四核心…

ACL和NAT

文章目录 ACL和NAT一、ACL概述及产生背景1、ACL访问控制列表2、ACL工作原理3、ACL种类4、ACL命令配置步骤4.1 ACL命令配置4.1 ACL配置步骤 二、NAT&#xff08;网络地址转换&#xff09;1、NAT概述2、NAT类型2.1 静态NAT与动态NAT 3、NATPT&#xff08;端口映射&#xff09;4、…