• 【Filter 过滤器、Listener 监听器基础】


    【Filter 过滤器、Listener 监听器基础】

    一、 Filter 过滤器

    1. Filter 过滤器概念

    生活中的过滤器:净水器、空气净化器等
    web 中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能

    • 过滤器的作用:
      一般用于完成通过的操作:
    • 如:登录验证
      统一编码处理
      敏感字符过滤……

    2. 快速入门

    • 步骤:

      1. 定义一个类,实现接口 Filter
      2. 复写方法
      3. 配置拦截路径
        • 配置 web.xml
        • 注解(常用)
    • 注解使用:

    @WebFilter("/*") // 访问所有资源之前,都会执行该过滤器
    public class FilterTest01 implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            Filter.super.init(filterConfig);
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("FilterTest01 被执行了!");
            // 放行,否则不会显示访问内容
            filterChain.doFilter(servletRequest, servletResponse);
        }
    
        @Override
        public void destroy() {
            Filter.super.destroy();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 配置 web.xml
    
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
        <filter>
            <filter-name>test01filter-name>
            <filter-class>com.example.filter_listener_test.FilterTest01filter-class>
        filter>
        <filter-mapping>
            <filter-name>test01filter-name>
            <url-pattern>/*url-pattern>
            
        filter-mapping>
    web-app>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3. 过滤器执行流程

    1. 执行过滤器
    2. 执行放行后的资源
    3. 回来执行过滤器放行下边的代码
    • 放行之前:对 request 对象请求消息增强
    • 放行之后:对 response 对象的响应消息增强
    @WebFilter("/*")
    public class FilterTest02 implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            Filter.super.init(filterConfig);
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            // 对 request 对象请求消息增强
            System.out.println("FilterTest02 执行了!");
            filterChain.doFilter(servletRequest, servletResponse);
            // 放行之后的代码
            // 对 response 对象的响应消息增强
            System.out.println("FilterTest02 返回了!");
        }
    
        @Override
        public void destroy() {
            Filter.super.destroy();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    4. 过滤器生命周期方法

    1. init 方法:在服务器启动后,会创建 Filter 对象,然后调用 init 方法,只会执行一次,用于加载资源
    2. doFilter 方法:每一次请求被拦截时,会执行,可以执行多次
    3. destroy 方法:在服务器关闭后,Filter 对象被销毁,如果服务器正常关闭,则会正常执行 destroy 方法,只会执行一次,用于释放资源
    @WebFilter("/*")
    public class FilterTest03 implements Filter {
        /**
         * 在服务器启动后,会创建 Filter 对象,然后调用 init 方法,只会执行一次,用于加载资源
         * @param filterConfig
         * @throws ServletException
         */
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("init 方法!");
            Filter.super.init(filterConfig);
        }
    
        /**
         * 每一次请求被拦截时,会执行,可以执行多次
         * @param servletRequest
         * @param servletResponse
         * @param filterChain
         * @throws IOException
         * @throws ServletException
         */
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("doFilter 方法!");
        }
    
        /**
         * 在服务器关闭后,Filter 对象被销毁,如果服务器正常关闭,则会正常执行 destroy 方法,只会执行一次,用于释放资源
         */
        @Override
        public void destroy() {
            System.out.println("destroy 方法!");
            Filter.super.destroy();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    5. 过滤器配置详解

    (1) 拦截路径配置
    1. 具体资源路径配置:/index.jsp → 只有访问 index.jsp 资源时,过滤器才会被执行
    2. 拦截目录:/user/* → 访问 /user 路径下的所有资源时,过滤器都会被执行
    3. 后缀名拦截:*.jsp → 访问所有后缀名为 jsp 资源时,过滤器都会被执行
    4. 拦截所有资源:/* → 访问所有资源时,多滤器都会被执行
    // @WebFilter("/index.jsp") // 具体资源路径配置:/index.jsp → 只有访问 index.jsp 资源时,过滤器才会被执行
    // @WebFilter("/user/*") // 拦截目录:/user/* → 访问 /user 路径下的所有资源时,过滤器都会被执行
    @WebFilter("*.jsp") // 后缀名拦截:*.jsp → 访问所有后缀名为 jsp 资源时,过滤器都会被执行
    // @WebFilter("/*") // 拦截所有资源:/* → 访问所有资源时,多滤器都会被执行
    public class FilterTest04 implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            Filter.super.init(filterConfig);
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("FilterTest04 执行!");
            filterChain.doFilter(servletRequest, servletResponse);
        }
    
        @Override
        public void destroy() {
            Filter.super.destroy();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    @WebServlet("/user/findAllServlet")
    public class ServletTest01 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("findAllServlet 开启!");
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doGet(request, response);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    @WebServlet("/user/updateServlet")
    public class ServletTest02 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("updateServlet 开启!");
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doGet(request, response);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    (1) 拦截方式配置

    拦截方式配置:资源被访问的方式

    1. 注解配置
      • 设置 dispatcherTypes 属性
        1. REQUEST:默认值,浏览器直接请求数据
        2. FORWARD:转发访问资源
        3. INCLUDE:包含访问资源
        4. ERROR:错误跳转资源
        5. ASYNC:异步访问资源
    2. web.xml 配置:配置 标签即可
    // 浏览器直接请求资源时,该过滤器会被执行
    // @WebFilter(value = "/index.jsp",dispatcherTypes = DispatcherType.REQUEST)
    // 浏览器只有转发访问 index.jsp 时,过滤器才会被执行
    // @WebFilter(value = "/index.jsp",dispatcherTypes = DispatcherType.FORWARD)
    // 配置多个,浏览器直接请求资源或者转发访问,过滤器会被执行
    @WebFilter(value = "/index.jsp",dispatcherTypes ={ DispatcherType.FORWARD,DispatcherType.REQUEST})
    public class FilterTest05 implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            Filter.super.init(filterConfig);
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("filterTest05 被访问了!");
            filterChain.doFilter(servletRequest, servletResponse);
        }
    
        @Override
        public void destroy() {
            Filter.super.destroy();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    @WebServlet("/user/updateServlet")
    public class ServletTest02 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("updateServlet 开启!");
            // 转发到 index.jsp
            request.getRequestDispatcher("/index.jsp").forward(request,response);
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doGet(request, response);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    	<filter>
            <filter-name>test01filter-name>
            <filter-class>com.example.filter_listener_test.FilterTest01filter-class>
        filter>
        <filter-mapping>
            <filter-name>test01filter-name>
            <url-pattern>/*url-pattern>
            <dispatcher>REQUESTdispatcher>
        filter-mapping>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    6. 过滤器链(配置多个过滤器)

    • 执行顺序:如果有两个过滤器:过滤器1和过滤器2
      1. 过滤器1
      2. 过滤器2
      3. 资源执行
      4. 过滤器2
      5. 过滤器1
    @WebFilter("/*")
    public class FilterTest06 implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            Filter.super.init(filterConfig);
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("filterTest06 执行了!");
            filterChain.doFilter(servletRequest, servletResponse);
            System.out.println("filterTest06 回来执行了!");
        }
    
        @Override
        public void destroy() {
            Filter.super.destroy();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    @WebFilter("/*")
    public class FilterTest07 implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            Filter.super.init(filterConfig);
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("filterTest07 执行了!");
            filterChain.doFilter(servletRequest, servletResponse);
            System.out.println("filterTest07 回来执行了!");
        }
    
        @Override
        public void destroy() {
            Filter.super.destroy();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    访问 index.jsp 执行结果:

    1. filterTest06 执行了!
    2. filterTest07 执行了!
    3. index.jsp 页面
    4. filterTest07 回来执行了!
    5. filterTest06 回来执行了!
    • 由此引出:过滤器先后顺序问题:
      1. 注解配置:按照类名的字符串比较规则比较,值小的先执行
        • 例如:AFilter 和 BFilter ,AFilter 就先执行
      2. web.xml 配置:在 标签中,谁定义在上边,谁就先执行

    7. 更改 Filter 代码模板

    • 如图所示位置更改代码模板,更方便创建格式化代码
      更改
    • 更改为如下样式:
    #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
    #parse("File Header.java")
    
    #if ($JAVAEE_TYPE == "jakarta")
    import jakarta.servlet.*;
    import jakarta.servlet.annotation.*;
    #else
    import javax.servlet.*;
    import javax.servlet.annotation.*;
    #end
    import java.io.IOException;
    
    @WebFilter(filterName = "${Entity_Name}")
    public class ${Class_Name} implements Filter {
        public void init(FilterConfig config) throws ServletException {
        }
    
        public void destroy() {
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
            chain.doFilter(request, response);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 创建 Filter 类,选择 Web 筛选器
      筛选器

    8. 案例

    (1) 登录验证

    案例资源【JSP 基础】
    其中的案例进行优化配置

    • 需求:

      • 访问案例的资源,验证其是否登录
      • 如果登录了,则直接放行
      • 如果没有登陆。则跳转到登录界面,提示“您尚未登录,请先登录!”
    • 分析:在案例资源中编写 LoginFilter 过滤器

      • 首先,判断是否是登录相关的资源
        1. 是,直接放行
        2. 不是,判断是否登录
      • 其次,判断当前用户是否登录,判断 Session 中是否有 User
        • 有,已经登录,放行
        • 没有,没有登录,跳转到登录页面
    @WebFilter("/*")
    public class LoginFilter implements Filter {
        public void init(FilterConfig config) throws ServletException {
        }
    
        public void destroy() {
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
            // 由于此 ServletRequest 对象中没有 Request 对象,所以要进行强制转换
            HttpServletRequest requestA=(HttpServletRequest) request;
            // 1. 获取资源请求路径
            String uri= requestA.getRequestURI();
            // 2. 判断是否包含登录相关的资源路径(CSS、JavaScript、图片、验证码等样式资源)
            if (uri.contains("/login.jsp")||uri.contains("/loginServlet")||uri.contains("/css/")||uri.contains("/js/")||uri.contains("/fonts/")||uri.contains("/checkCodeServlet")){
                // 包含,说明用户想要登录,或者正在登录界面,放行
                chain.doFilter(request,response);
            }else {
                // 不包含,需要验证用户是否登录
                // 3. 从获取的 Session 中获取 user
                Object user = requestA.getSession().getAttribute("user");
                if (user!=null){
                    // 登录了,放行
                    chain.doFilter(request,response);
                }else {
                    // 没有登录,跳转登录界面
                    requestA.setAttribute("login_msg","您尚未登录,请先登录!");
                    // 进行页面跳转
                    requestA.getRequestDispatcher("/login.jsp").forward(requestA,response);
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    (2) 敏感词汇过滤
    ① 案例分析
    • 需求:
      1. 对案例资源录入的数据进行敏感词汇过滤(同上述案例的案例资源)
      2. 敏感词汇设置,在这里直接做成文本文档,之后导入使用
      3. 如果是敏感词汇,替换为 **
    • 分析:
      • 由于原本的 Request 对象并不具备这样的替换方法
        1. 所以对 Request 对象的 getParameter() 方法进行增强,产生一个新的 Request 对象(增强获取参数相关方法)
        2. 放行,将新的 Request 对象传入(传递代理对象)
      • 所以主要就是对 Request 对象进行增强
    ② 通过动态代理增强方法
    • 增强对象的功能
      • 设计模式:一些通用的解决固定问题的方式 设计模式百度百科
      • 此处适合使用的:
        1. 装饰模式:(较为复杂)
        2. 代理模式:(较为简单灵活)
          • 概念:
            1. 真实对象:被代理的对象
            2. 代理对象
            3. 代理模式:代理对象代理真实对象,达到增强真实对象功能的目的
          • 实现方式:
            1. 静态代理:有一个类文件描述代理模式
            2. 动态代理:在内存中形成代理类
              • 实现步骤:
                1. 代理对象和真实对象实现相同的接口
                2. 代理对象 = Proxy.newProxyInstance();
                3. 使用代理对象调用方法
                4. 增强方法
              • 增强方式:
                1. 增强参数列表
                2. 增强返回值类型
                3. 增强方法体执行逻辑
    Ⅰ、 简单使用动态代理

    简单了解使用动态代理

    • 定义一个接口
    public interface SalePhone {
        public String sale(double money);
        public void show();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 真是类实现接口
    /**
     * 真实类
     */
    public class Apple implements SalePhone{
        @Override
        public String sale(double money) {
            System.out.println("花费"+money+"元买了一台苹果手机!");
            return "苹果手机";
        }
    
        @Override
        public void show() {
            System.out.println("展示苹果手机!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 动态代理测试
    public class ProxyTest {
        public static void main(String[] args) {
            // 1. 创建真实对象
            Apple apple = new Apple();
            // 2. 动态代理增强 Apple 对象
            /*
            * 三个参数:
            *   1. 类加载器:真实对象.getClass().getClassLoader()
            *   2. 接口数组:真实对象.getClass().getInterfaces()
            *   3. 处理器:new InvocationHandler()
            */
            SalePhone proxy_apple = (SalePhone) Proxy.newProxyInstance(apple.getClass().getClassLoader(), apple.getClass().getInterfaces(), new InvocationHandler() {
                /*
                * 代理逻辑编写的方法:代理对象调用的所有方法都会触发该方法执行
                *  参数:
                *   1. proxy:代理对象
                *   2. method:代理对象调用的方法,被封装为的对象
                *   3. args:代理对象调用的方法,传递的实际参数
                */
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    // 增强代码逻辑就会在这个方法中编写并执行
                    System.out.println("该方法执行了!");
                    System.out.println(method.getName());
                    System.out.println(args[0]);
                    return null;
                }
            });
            // 3. 调用方法
            String phone = proxy_apple.sale(8999);
            System.out.println(phone);
            // proxy_apple.show();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    Ⅱ、 使用动态代理增强某些功能

    简单练习动态代理的增强方式,增强某些功能

    public class ProxyTest {
        public static void main(String[] args) {
            // 1. 创建真实对象
            Apple apple = new Apple();
            // 2. 动态代理增强 Apple 对象
            SalePhone proxy_apple = (SalePhone) Proxy.newProxyInstance(apple.getClass().getClassLoader(), apple.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    // 判断是否是 sale 方法
                    if (method.getName().equals("sale")){
                        // 1. 增强参数
                        double money=(double) args[0];
                        money=money*0.85;
                        System.out.println("专车接送用户!");
                        // 使用真实对象调用改方法
                        Object obj = method.invoke(apple, money);
                        System.out.println("免费送货上门!");
                        // 2. 增强返回值
                        return obj+"+附赠+充电器";
                    }else {
                        Object obj = method.invoke(apple, args);
                        return obj;
                    }
    
                }
            });
            // 3. 调用方法
            String phone = proxy_apple.sale(8999);
            System.out.println(phone);
            proxy_apple.show();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    ③ 案例实现

    敏感词汇.txt 文件导入到 IDEA 中配置文件 resources 资源目录下(Maven 框架下的 resources 资源目录 【Maven 基础】),如果没有使用 Maven 框架则直接将配置文件放在 src/com 目录下
    注意:编码格式的更改,防止乱码

    辣鸡
    笨猪
    牛逼
    
    • 1
    • 2
    • 3
    • 实现:
    @WebFilter("/*")
    public class SensitiveWordsFilter implements Filter {
        // 存放敏感词汇的集合
        private List<String> list=new ArrayList<>();
        public void init(FilterConfig config) throws ServletException {
            try {
                // 1. 获取文件的真实路径
                ServletContext servletContext = config.getServletContext();
                String realPath = servletContext.getRealPath("/WEB-INF/classes/敏感词汇.txt");
                // 2. 读取文件
                BufferedReader bufferedReader = new BufferedReader(new FileReader(realPath));
                // 3. 将文件的每一行数据添加到 list 集合中
                String line=null;
                while ((line=bufferedReader.readLine())!=null){
                    list.add(line);
                }
                bufferedReader.close();
                System.out.println(list);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public void destroy() {
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
            // 1. 创建代理对象,增强 getParameter 方法
            ServletRequest proxy_request = (ServletRequest)Proxy.newProxyInstance(request.getClass().getClassLoader(), request.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    // 增强 getParameter 方法
                    // 判断是否是 getParameter 方法
                    if (method.getName().equals("getParameter")){
                        // 增强返回值
                        // 获取返回值
                        String value=(String) method.invoke(request,args);
                        if (value!=null){
                            for (String str :list) {
                                if (value.contains(str)){
                                    value=value.replaceAll(str,"**");
                                }
                            }
                        }
                        return value;
                    }
                    return method.invoke(request,args);
                }
            });
            // 判断方法名是否是 getParameterMap
            // 判断方法名是否是 getParameterValue
            // 2. 放行
            chain.doFilter(proxy_request, response);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 测试类:
    @WebServlet("/testServlet")
    public class TestServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String name=request.getParameter("name");
            String msg = request.getParameter("msg");
            System.out.println(name+":"+msg);
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doGet(request, response);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 访问方式:浏览器中输入 http://localhost:8080/test/testServlet?name=张三&msg=你个大辣鸡(具体要查看自己的资源访问路径)

    二、 Listener 监听器

    1. Listener 监听器概述

    Web 三大组件之一

    • 事件监听机制
      • 事件:一件事情
      • 事件源:事件发生的地方
      • 监听器:一个对象
      • 注册监听:将事件、事件源、监听器绑定在一起。当事件源上发生某个事件后,执行监听器代码

    2. ServletContextListener 接口

    监听 ServletContext 对象的创建和销毁

    • void contextDestroyed(ServletContextEvent sce) :ServletContext 对象被销毁之前会调用该方法
    • void contextInitialized(ServletContextEvent sce) :ServletContext 对象创建后会调用该方法
    (1) 使用步骤
    1. 定义一个类,实现 ServletContextListener 接口
    2. 复写方法
    3. 配置
      1. web.xml
      2. 注解配置
    (2) 简单使用
    public class ContextLoaderListener implements ServletContextListener {
        /**
         * 用于监听 ServletContext 对象的创建,ServletContext 对象服务器启动后自动创建
         * 该方法在服务器启动后自动调用
         * @param sce
         */
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            System.out.println("ServletContext 对象被创建了!");
        }
    
        /**
         * 在服务器关闭后,ServletContext 对象被销毁,当服务器正常关闭后该方法被调用
         * @param sce
         */
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            System.out.println("ServletContext 对象被销毁了!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 配置 web.xml 即可使用
        
        <listener>
            <listener-class>com.example.filter_listener_test.ContextLoaderListenerlistener-class>
        listener>
    
    • 1
    • 2
    • 3
    • 4
    • 或者使用注解配置,即在类的开头加上 @WebListener 注解
    (3) 详细讲解接口中方法的使用
    public class ContextLoaderListener implements ServletContextListener {
        /**
         * 用于监听 ServletContext 对象的创建,ServletContext 对象服务器启动后自动创建
         * 该方法在服务器启动后自动调用
         * @param sce
         */
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            // 加载资源文件
            // 1. 获取 ServletContext 对象
            ServletContext servletContext = sce.getServletContext();
            // 2. 加载资源文件
            String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");
            // 3. 获取真实路径
            String realPath = servletContext.getRealPath(contextConfigLocation);
            // 4. 加载进内存
            try {
                FileInputStream fileInputStream = new FileInputStream(realPath);
                // 打印,判断是否获取到流对象
                System.out.println(fileInputStream);
            }catch (Exception e){
                e.printStackTrace();
            }
            System.out.println("ServletContext 对象被创建了!");
        }
    
        /**
         * 在服务器关闭后,ServletContext 对象被销毁,当服务器正常关闭后该方法被调用
         * @param sce
         */
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            System.out.println("ServletContext 对象被销毁了!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • web.xml 配置:
        
        <listener>
            <listener-class>com.example.filter_listener_test.ContextLoaderListenerlistener-class>
        listener>
            
        <context-param>
            <param-name>contextConfigLocationparam-name>
            <param-value>/WEB-INF/classes/applicationContext.xmlparam-value>
        context-param>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 添加一个配置文件 applicationContext.xml 配置文件,如果使用 Maven 框架,则将该文件放到 resources 资源目录下(Maven 框架下的 resources 资源目录 【Maven 基础】),如果没有使用 Maven 框架则直接将配置文件放在 src/com 目录下
    
    <bean>bean>
    
    • 1
    • 2
  • 相关阅读:
    Flink SQL: SHOW Statements
    P1631 序列合并,思维,优先队列
    一些关于字节序处理的一些经验
    Python单例模式(3种常用方式)
    如何通过反射访问一个类的私有方法
    3.1、数据链路层概述
    NFNet:NF-ResNet的延伸,不用BN的4096超大batch size训练 | 21年论文
    介绍各个PHP版本一些特性知识点
    【Excel VBA和Python对照学习】创建字典
    Intel 高性能库之IPP信号处理简介及下载(版本5.1、6.1,含32位和64位及注册)
  • 原文地址:https://blog.csdn.net/Jade_Heng_Star/article/details/126180471