Spring Boot中的过滤器、拦截器、监听器技巧汇总:让你快速成为大神

举报
bug菌 发表于 2023/10/11 17:16:01 2023/10/11
【摘要】 🏆本文收录于《Spring Boot从入门到精通》,专门攻坚指数提升,2023 年国内最系统+最强(更新中)。


🏆本文收录于《Spring Boot从入门到精通》,专门攻坚指数提升,2023 年国内最系统+最强(更新中)。

本专栏致力打造最硬核Spring Boot 系列教程,从零基础到进阶系列学习内容,🚀均为全网独家首发,打造精品专栏,专栏持续更新中…欢迎大家订阅持续学习。

环境说明:Windows10 + Idea2021.3.2 + Jdk1.8 + SpringBoot 2.3.1.RELEASE

前言

在Web应用程序中,我们经常需要处理请求和响应。有时,我们需要应用于所有请求和响应的通用逻辑。这就是过滤器、拦截器和监听器的用武之地。它们可以帮助我们在请求和响应被处理之前或之后执行一些通用逻辑。

摘要

本文将介绍在Spring Boot应用程序中使用过滤器、拦截器和监听器的技巧。我们将讨论它们之间的区别,以及何时使用它们。我们还将提供代码示例,以帮助您在自己的应用程序中使用它们。

正文

过滤器

过滤器是在请求进入Servlet容器之前或响应离开容器之后执行的,用于在处理请求或响应之前/之后修改它们。 在Spring Boot中,我们可以使用Filter接口实现一个过滤器。以下是一个示例:

@Component
public class MyFilter implements Filter {

    @Override
    public void doFilter(
      ServletRequest request, 
      ServletResponse response, 
      FilterChain chain) throws IOException, ServletException {
 
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
 
        // 执行一些通用逻辑
        System.out.println(
          "Logging Request  {} : {}" + req.getMethod() + " " + 
          req.getRequestURI());
 
        // 继续处理请求
        chain.doFilter(request, response);
 
        // 执行一些通用逻辑
        System.out.println(
          "Logging Response :{}" + 
          res.getContentType());
    }
 
    // 省略掉其他方法
}

在上面的示例中,我们定义了一个名为MyFilter的过滤器。它将在请求进入Servlet容器之前和离开容器之后执行。我们可以在此处执行一些通用逻辑,如记录请求/响应、修改请求/响应等。

为了将此过滤器应用于我们的应用程序,我们需要将其注册到Spring Boot应用程序中。我们可以使用@ServletComponentScan注释自动扫描我们的过滤器。例如:

@SpringBootApplication
@ServletComponentScan
public class MyApp {
 
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }
}

拦截器

拦截器与过滤器类似,但它们提供更灵活的方式来处理请求和响应。拦截器只能与Spring MVC一起使用,它们允许我们在控制器处理请求之前或之后执行逻辑。 拦截器可以为包含控制器的所有请求执行通用逻辑,同时还可以为每个控制器或每个请求执行特定逻辑。

在Spring Boot中,我们可以使用HandlerInterceptor接口实现一个拦截器。以下是一个示例:

@Component
public class MyInterceptor implements HandlerInterceptor {
 
    @Override
    public boolean preHandle(
      HttpServletRequest request, 
      HttpServletResponse response, 
      Object handler) throws Exception {
 
        // 执行一些通用逻辑
        System.out.println(
          "Logging Request  {} : {}" + 
          request.getMethod() + " " + request.getRequestURI());
 
        return true;
    }
 
    // 省略掉其他方法
}

在上面的示例中,我们定义了一个名为MyInterceptor的拦截器。它将在控制器处理请求之前执行。我们可以在此处执行一些通用逻辑,如记录请求、验证请求参数等。

为了将此拦截器应用于我们的应用程序,我们需要将其注册到Spring Boot应用程序中。我们可以使用WebMvcConfigurer接口来注册拦截器。例如:

@Configuration
public class AppConfig implements WebMvcConfigurer {
 
    @Autowired
    private MyInterceptor myInterceptor;
 
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor);
    }
}

在上面的示例中,我们将MyInterceptor添加到拦截器注册表中。

监听器

监听器是在Spring应用程序中处理事件的通用机制。 Spring Boot应用程序中的事件可以是Web请求、应用程序启动/停止等。 监听器可以监听这些事件,并在事件发生时执行一些逻辑。

在Spring Boot中,我们可以使用ApplicationListener接口实现一个监听器。以下是一个示例:

@Component
public class MyAppListener 
  implements ApplicationListener<ApplicationEvent> {
 
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
 
        // 处理事件
        System.out.println("Event: " + event.getClass());
    }
}

在上面的示例中,我们定义了一个名为MyAppListener的监听器。它将在应用程序中的任何事件发生时执行。我们可以在此处执行一些逻辑,如记录事件、修改应用程序状态等。

为了将此监听器应用于我们的应用程序,我们需要将其注册到Spring Boot应用程序中。我们可以使用@Component注释将其定义为组件。

代码方法介绍

过滤器

在上面的示例中,我们实现了一个名为MyFilter的过滤器。以下是一些在过滤器中使用的常见方法:

  • doFilter:执行过滤器逻辑。可以在此处修改请求和响应。
  • init:初始化过滤器。在过滤器实例化时调用。
  • destroy:销毁过滤器。在过滤器销毁时调用。

拦截器

在上面的示例中,我们实现了一个名为MyInterceptor的拦截器。以下是一些在拦截器中使用的常见方法:

  • preHandle:在控制器处理请求之前执行。可以在此处验证请求、记录请求等。
  • postHandle:在控制器处理请求之后执行,但在响应发送到客户端之前。可以在此处修改响应、记录响应等。
  • afterCompletion:在响应发送到客户端之后执行。可以在此处记录响应等。

监听器

在上面的示例中,我们实现了一个名为MyAppListener的监听器。以下是一些在监听器中使用的常见方法:

  • onApplicationEvent:处理事件。可以在此处记录事件、修改应用程序状态等。

优缺点

过滤器(Filter):

优点:

  1. 可以拦截请求和响应,且处理请求和响应方便;
  2. 可以对请求进行预处理和后处理,如字符编码转换、session管理等;
  3. 可以实现对特定URL或者路径进行特定的处理和拦截;
  4. 可以与Servlet容器无缝结合,使用方便。

缺点:

  1. 无法获取Servlet容器的上下文信息;
  2. 无法操作HttpServletRequest和HttpServletResponse对象,只能读取其中的信息和设置信息;
  3. 过滤器只能拦截Servlet请求,不能拦截其他的请求;
  4. 过滤器只能对请求进行处理,无法对响应进行处理;
  5. 过滤器执行顺序不能保证。

拦截器(Interceptor):

优点:

  1. 可以拦截请求和响应,且处理请求和响应方便;
  2. 可以获取Servlet容器的上下文信息;
  3. 可以操作HttpServletRequest和HttpServletResponse对象;
  4. 可以对请求进行预处理和后处理;
  5. 可以实现对特定URL或者路径进行特定的处理和拦截;
  6. 可以对Controller方法进行权限控制。

缺点:

  1. 对于Servlet容器没有直接的支持,需要进行额外的配置;
  2. 拦截器只能在Spring MVC中使用。

监听器(Listener):

优点:

  1. 可以监听Servlet容器的生命周期事件,如初始化、销毁等;
  2. 可以监听HttpServletRequest和HttpServletResponse对象的创建和销毁;
  3. 可以实现对ServletContext、HttpSession和ServletRequest等对象的监听。

缺点:

  1. 只能对事件进行监听,无法对请求进行处理;
  2. 监听器执行顺序不能保证;
  3. 监听器只对WEB应用程序有效。

三者对比

过滤器、拦截器和监听器都是用于对应用程序进行特定处理的工具,但它们具有不同的工作方式和用途。

  1. 过滤器(Filter)
    过滤器是Servlet规范中的一种组件,用于拦截Web应用程序的请求和响应,可以对请求进行预处理,也可以在响应被发送到客户端之前对其进行后处理。过滤器通常用于实现安全性、日志记录、压缩、字符编码转换等功能。其优点是可以在Web容器的级别上对请求进行统一处理,缺点是只能在Servlet规范的范围内使用。

  2. 拦截器(Interceptor)
    拦截器是Spring MVC框架中的一种组件,用于拦截和处理请求和响应。与过滤器不同,拦截器可以在请求被处理前和被处理后执行一些其它的逻辑,比如安全性、日志记录、性能监测、事务管理等。拦截器可以在Spring MVC框架的任意层级上使用,其优点是灵活性高,缺点是需要在代码中显式引用。

  3. 监听器(Listener)
    监听器是Java Servlet规范中的一种组件,用于监听Web应用程序的事件,比如ServletContext、HttpSession和ServletRequest等事件。它可以在应用程序运行时动态地捕获这些事件,并执行一些相应的逻辑。其优点是能够监听应用程序的各种事件并根据需要进行相应的处理,缺点是只能监听一些特定的事件。

综上所述,过滤器、拦截器和监听器都有其各自的适用场合和优缺点。过滤器适用于对请求和响应进行统一处理的场合;拦截器适用于在请求被处理前后执行一些其它的逻辑的场合;监听器适用于对应用程序的事件进行监听和处理的场合。

附录源码

  如上涉及所有源码均已上传同步在「GitHub」,提供给同学们一对一参考学习,辅助你更迅速的掌握。

总结

在Web应用程序开发中,过滤器、拦截器和监听器都是常用的工具,用于在处理请求和响应之前或之后执行特定的逻辑。过滤器可以在请求进入Servlet容器之前或响应离开容器之后执行,拦截器只能与Spring MVC一起使用,在控制器处理请求之前或之后执行逻辑,监听器可以在应用程序中处理事件。三种工具各有优缺点,使用场景也不一样。根据需求选择适合的工具可以提高开发效率和应用程序质量。

☀️建议/推荐你


无论你是计算机专业的学生,还是对编程有兴趣的小伙伴,都建议直接毫无顾忌的学习此专栏「滚雪球学Spring Boot」,从入门到精通,凡是学习此专栏的同学,均能获取到所需的知识和技能,全网最快速入门SpringBoot,就像滚雪球一样,越滚越大,指数级提升。

  最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。

  同时欢迎大家关注公众号:「猿圈奇妙屋」 ,以便学习更多同类型的技术文章,免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板、技术文章Markdown文档等海量资料。

📣关于我

我是bug菌,CSDN | 掘金 | InfoQ | 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计15w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等海量资料。


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。