【Spring Boot实战与进阶】过滤器和拦截器的使用及其区别

简介: 过滤器和拦截器的使用及其区别
Spring Boot是很优秀的框架,它的出现简化了新Spring应用的初始搭建以及开发过程,大大减少了代码量,目前已被大多数企业认可和使用。这个专栏将对Spring Boot框架从浅入深,从实战到进阶,不但我们要懂得如何去使用,还要去剖析框架源码,学习其优秀的设计思想。

汇总目录链接:【Spring Boot实战与进阶】学习目录

一、过滤器

  过滤器是处于客户端与服务器资源文件之间的一道过滤网,在访问资源文件之前,通过一系列的过滤器对请求进行修改、判断等,把不符合规则的请求在中途拦截或修改。也可以对响应进行过滤,拦截或修改响应。

1、自定义一个TimeFilter类

@Component
@WebFilter(urlPatterns = {"/*"})
public class TimeFilter implements Filter{
    Logger log = LoggerFactory.getLogger(Logger.class);
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("【过滤器】初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("【过滤器】开始执行");
        Long startTime = System.currentTimeMillis();
        filterChain.doFilter(servletRequest, servletResponse);
        log.info("【过滤器】耗时:" + (System.currentTimeMillis() - startTime)+"ms");
        log.info("【过滤器】结束执行");
    }

    @Override
    public void destroy() {
        log.info("【过滤器】销毁");
    }
}
AI 代码解读

2、配置方式

  • @WebFilter注解的urlPatterns属性配置了哪些请求可以进入该过滤器,/*表示所有请求。
  • 除了在过滤器类上加注解外,我们也可以通过FilterRegistrationBean来注册过滤器。定义一个TimeFilterConfig类,加上@Configuration注解表明其为配置类,然后通过FilterRegistrationBean来注册过滤器。
public class TimeFilterConfig {
    @Bean
    public FilterRegistrationBean timeFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        TimeFilter timeFilter = new TimeFilter();
        filterRegistrationBean.setFilter(timeFilter);

        List<String> urlList = new ArrayList<>();
        urlList.add("/*");

        filterRegistrationBean.setUrlPatterns(urlList);
        return filterRegistrationBean;
    }
}
AI 代码解读

3、项目演示

@RestController
public class HelloController {
    Logger log = LoggerFactory.getLogger(Logger.class);

    @RequestMapping("hello")
    public void hello(){
        log.info("Controller:Hello World!");
    }
}
AI 代码解读

启动项目,可以在控制台看到输出了过滤器初始化,访问http://localhost:8080/hello

控制台输出

【过滤器】开始执行
Controller:Hello World!
【过滤器】耗时:26ms
【过滤器】结束执行
AI 代码解读

二、拦截器

  拦截器,是面向切面编程(AOP,Aspect Oriented Program)的。就是在Service或者一个方法前调用一个方法,或者在方法后调用一个方法。比如动态代理就是拦截器的简单实现,在调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在调用方法后打印出字符串,甚至在抛出异常的时候做业务逻辑的操作。

1、定义一个TimeInterceptor类

@Component
public class TimeInterceptor implements HandlerInterceptor {
    Logger log = LoggerFactory.getLogger(Logger.class);
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        log.info("【拦截器】处理前");
        httpServletRequest.setAttribute("startTime", System.currentTimeMillis());
        log.info(((HandlerMethod) o).getBean().getClass().getName());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        log.info("【拦截器】处理中");
        Long start = (Long) httpServletRequest.getAttribute("startTime");
        log.info("【拦截器】耗时:" + (System.currentTimeMillis() - start)+"ms");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        log.info("【拦截器】处理后");
        Long start = (Long) httpServletRequest.getAttribute("startTime");
        log.info("【拦截器】耗时:" + (System.currentTimeMillis() - start)+"ms");
    }
}
AI 代码解读

2、在TimeInterceptorConfig中通过InterceptorRegistry注册过滤器。

@Configuration
public class TimeInterceptorConfig extends WebMvcConfigurerAdapter {
    @Autowired
    private TimeInterceptor timeInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(timeInterceptor);
    }
}
AI 代码解读

3、项目演示

@RestController
public class HelloController {
    Logger log = LoggerFactory.getLogger(Logger.class);

    @RequestMapping("hello")
    public void hello(){
        log.info("Controller:Hello World!");
    }
}
AI 代码解读

启动项目,访问http://localhost:8080/hello

控制台输出

【拦截器】处理前
com.boot.filter.controller.HelloController
Controller:Hello World!
【拦截器】处理中
【拦截器】耗时:22ms
【拦截器】处理后
【拦截器】耗时:22ms
AI 代码解读

三、过滤器和拦截器的区别

主要区别:
1、拦截器是基于Java的反射机制的,而过滤器是基于函数回调。
2、拦截器不依赖于servlet容器,过滤器依赖于servlet容器。
3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
6、拦截器可以获取IOC容器中的各个bean(基于FactoryBean接口 ),而过滤器就不行,在拦截器里注入一个service,可以调用业务逻辑。

本质区别:
   从灵活性上说拦截器功能更强大些,Filter能做的事情它都能做,而且可以在请求前,请求后执行,比较灵活。Filter主要是针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验,其他的还是建议用interceptor。

执行顺序:

【过滤器】开始执行
【拦截器】处理前
com.boot.filter.controller.HelloController
Controller:Hello World!
【拦截器】处理中
【拦截器】耗时:20ms
【拦截器】处理后
【拦截器】耗时:20ms
【过滤器】耗时:27ms
【过滤器】结束执行
AI 代码解读

过滤前-----拦截前-----Action处理-----拦截后-----过滤后。
在这里插入图片描述

目录
打赏
0
0
0
0
513
分享
相关文章
|
1月前
|
基于SpringBoot的Redis开发实战教程
Redis在Spring Boot中的应用非常广泛,其高性能和灵活性使其成为构建高效分布式系统的理想选择。通过深入理解本文的内容,您可以更好地利用Redis的特性,为应用程序提供高效的缓存和消息处理能力。
161 79
深入解析HTTP请求方法:Spring Boot实战与最佳实践
这篇博客结合了HTTP规范、Spring Boot实现和实际工程经验,通过代码示例、对比表格和架构图等方式,系统性地讲解了不同HTTP方法的应用场景和最佳实践。
74 5
SpringBoot 实战 不同参数调用不同实现
本文介绍了如何在实际工作中根据不同的入参调用不同的实现,采用`map+enum`的方式实现优雅且严谨的解决方案。通过Spring Boot框架中的工厂模式或策略模式,避免了使用冗长的`if...else...`语句。文中详细展示了定义接口、实现类、枚举类以及控制器调用的代码示例,确保用户输入的合法性并简化了代码逻辑。
SpringBoot 实战 不同参数调用不同实现
Spring Boot 两种部署到服务器的方式
本文介绍了Spring Boot项目的两种部署方式:jar包和war包。Jar包方式使用内置Tomcat,只需配置JDK 1.8及以上环境,通过`nohup java -jar`命令后台运行,并开放服务器端口即可访问。War包则需将项目打包后放入外部Tomcat的webapps目录,修改启动类继承`SpringBootServletInitializer`并调整pom.xml中的打包类型为war,最后启动Tomcat访问应用。两者各有优劣,jar包更简单便捷,而war包适合传统部署场景。需要注意的是,war包部署时,内置Tomcat的端口配置不会生效。
1203 17
Spring Boot 两种部署到服务器的方式
微服务——SpringBoot使用归纳——Spring Boot中使用拦截器——拦截器使用实例
本文主要讲解了Spring Boot中拦截器的使用实例,包括判断用户是否登录和取消特定拦截操作两大场景。通过token验证实现登录状态检查,未登录则拦截请求;定义自定义注解@UnInterception实现灵活取消拦截功能。最后总结了拦截器的创建、配置及对静态资源的影响,并提供两种配置方式供选择,帮助读者掌握拦截器的实际应用。
36 0
微服务——SpringBoot使用归纳——Spring Boot中使用拦截器——拦截器的快速使用
本文介绍了在Spring Boot中使用拦截器的方法,包括拦截器的基本原理、定义与配置步骤。拦截器是AOP的一种实现,主要用于拦截对动态资源的请求,如判断用户权限或结合WebSocket使用。文章详细讲解了通过实现`HandlerInterceptor`接口来自定义拦截器,并重写`preHandle`、`postHandle`和`afterCompletion`三个核心方法。
48 0
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——指定项目配置文件
在实际项目中,开发环境和生产环境的配置往往不同。为简化配置切换,可通过创建 `application-dev.yml` 和 `application-pro.yml` 分别管理开发与生产环境配置,如设置不同端口(8001/8002)。在 `application.yml` 中使用 `spring.profiles.active` 指定加载的配置文件,实现环境快速切换。本节还介绍了通过配置类读取参数的方法,适用于微服务场景,提升代码可维护性。课程源码可从 [Gitee](https://gitee.com/eson15/springboot_study) 下载。
54 0
Spring Cloud Alibaba与Spring Cloud区别和联系?
Spring Cloud Alibaba与Spring Cloud区别和联系?
Jeesite5:Star24k,Spring Boot 3.3+Vue3实战开源项目,架构深度拆解!让企业级项目开发效率提升300%的秘密武器
Jeesite5 是一个基于 Spring Boot 3.3 和 Vue3 的企业级快速开发平台,集成了众多优秀开源项目,如 MyBatis Plus、Bootstrap、JQuery 等。它提供了模块化设计、权限管理、多数据库支持、代码生成器和国际化等功能,极大地提高了企业级项目的开发效率。Jeesite5 广泛应用于企业管理系统、电商平台、客户关系管理和知识管理等领域。通过其强大的功能和灵活性,Jeesite5 成为了企业级开发的首选框架之一。访问 [Gitee 页面](https://gitee.com/thinkgem/jeesite5) 获取更多信息。
Jeesite5:Star24k,Spring Boot 3.3+Vue3实战开源项目,架构深度拆解!让企业级项目开发效率提升300%的秘密武器
京东面试:聊聊Spring事务?Spring事务的10种失效场景?加入型传播和嵌套型传播有什么区别?
45岁老架构师尼恩分享了Spring事务的核心知识点,包括事务的两种管理方式(编程式和声明式)、@Transactional注解的五大属性(transactionManager、propagation、isolation、timeout、readOnly、rollbackFor)、事务的七种传播行为、事务隔离级别及其与数据库隔离级别的关系,以及Spring事务的10种失效场景。尼恩还强调了面试中如何给出高质量答案,推荐阅读《尼恩Java面试宝典PDF》以提升面试表现。更多技术资料可在公众号【技术自由圈】获取。
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等