【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();
    }
}
  • 配置 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>test01</filter-name>
        <filter-class>com.example.filter_listener_test.FilterTest01</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>test01</filter-name>
        <url-pattern>/*</url-pattern>
        <!-- 拦截路径 -->
    </filter-mapping>
</web-app>

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();
    }
}

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();
    }
}

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();
    }
}
@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);
    }
}
@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) 拦截方式配置

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

  1. 注解配置
    • 设置 dispatcherTypes 属性
      1. REQUEST:默认值,浏览器直接请求数据
      2. FORWARD:转发访问资源
      3. INCLUDE:包含访问资源
      4. ERROR:错误跳转资源
      5. ASYNC:异步访问资源
  2. web.xml 配置:配置 <dispatcher></dispatcher> 标签即可
// 浏览器直接请求资源时,该过滤器会被执行
// @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();
    }
}
@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);
    }
}
	<filter>
        <filter-name>test01</filter-name>
        <filter-class>com.example.filter_listener_test.FilterTest01</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>test01</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

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();
    }
}
@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();
    }
}

访问 index.jsp 执行结果:

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

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);
    }
}
  • 创建 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);
            }
        }
    }
}
(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();
}
  • 真是类实现接口
/**
 * 真实类
 */
public class Apple implements SalePhone{
    @Override
    public String sale(double money) {
        System.out.println("花费"+money+"元买了一台苹果手机!");
        return "苹果手机";
    }

    @Override
    public void show() {
        System.out.println("展示苹果手机!");
    }
}
  • 动态代理测试
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();
    }
}
Ⅱ、 使用动态代理增强某些功能

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

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();
    }
}
③ 案例实现

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

辣鸡
笨猪
牛逼
  • 实现:
@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);
    }
}
  • 测试类:
@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);
    }
}
  • 访问方式:浏览器中输入 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 对象被销毁了!");
    }
}
  • 配置 web.xml 即可使用
    <!-- 配置监听器,注册监听-->
    <listener>
        <listener-class>com.example.filter_listener_test.ContextLoaderListener</listener-class>
    </listener>
  • 或者使用注解配置,即在类的开头加上 @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 对象被销毁了!");
    }
}
  • web.xml 配置:
    <!-- 配置监听器,注册监听-->
    <listener>
        <listener-class>com.example.filter_listener_test.ContextLoaderListener</listener-class>
    </listener>
        <!-- 指定初始化参数 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/classes/applicationContext.xml</param-value>
    </context-param>
  • 添加一个配置文件 applicationContext.xml 配置文件,如果使用 Maven 框架,则将该文件放到 resources 资源目录下(Maven 框架下的 resources 资源目录 【Maven 基础】),如果没有使用 Maven 框架则直接将配置文件放在 src/com 目录下
<?xml version="1.0" encoding="UTF-8" ?>
<bean></bean>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
拦截器、过滤器监听器是在软件开发中常用的三种组件,用于对请求进行干预、选择和获取事件细节。它们的区别如下[^1][^2]: 1. 拦截器(Interceptor): 拦截器用于在请求进行中干预其进展,并可以控制是否终止请求的执行。拦截器可以在请求前、请求后或请求完成后执行特定的操作,例如记录日志、权限验证等。 2. 过滤器Filter): 过滤器用于从一堆东西中选择符合特定要求的内容。它可以定义一些规则或条件,根据这些规则或条件来过滤出符合要求的内容。过滤器通常用于对请求进行预处理或后处理,例如请求参数的校验、字符编码的转换等。 3. 监听器Listener): 监听器用于获取事件发生的细节,而不对事件的执行过程进行干预。当特定事件发生时,监听器可以捕获该事件并执行相应的操作。监听器通常用于记录日志、统计数据等。 示例代码如下: ```java // 拦截器示例 public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 在请求前执行的操作 return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 在请求后执行的操作 } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 在请求完成后执行的操作 } } // 过滤器示例 public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 过滤器初始化操作 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 过滤器处理请求的操作 chain.doFilter(request, response); } @Override public void destroy() { // 过滤器销毁操作 } } // 监听器示例 public class MyListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { // 监听器初始化操作 } @Override public void contextDestroyed(ServletContextEvent sce) { // 监听器销毁操作 } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值