【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("【过滤器】销毁");
    }
}

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

3、项目演示

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

    @RequestMapping("hello")
    public void hello(){
        log.info("Controller:Hello World!");
    }
}

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

控制台输出

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

二、拦截器

  拦截器,是面向切面编程(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");
    }
}

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

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

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(timeInterceptor);
    }
}

3、项目演示

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

    @RequestMapping("hello")
    public void hello(){
        log.info("Controller:Hello World!");
    }
}

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

控制台输出

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

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

主要区别:
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
【过滤器】结束执行

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

相关文章
|
2月前
|
Java 容器
如何在SpringBoot项目中使用过滤器和拦截器
过滤器和拦截器是日常开发中常用技术,用于对特定请求进行增强处理,如插入自定义代码以实现特定功能。过滤器在请求到达 `servlet` 前执行,而拦截器在请求到达 `servlet` 后执行。`SpringBoot` 中的拦截器依赖于 `SpringBoot` 容器,过滤器则由 `servlet` 提供。通过实现 `Filter` 接口并重写 `doFilter()` 方法可实现过滤器;通过实现 `HandlerInterceptor` 接口并重写相应方法可实现拦截器。两者的主要区别在于执行时机的不同,需根据具体场景选择使用。
179 4
如何在SpringBoot项目中使用过滤器和拦截器
|
4天前
|
存储 运维 安全
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
14 2
|
1月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
52 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
24天前
|
自然语言处理 Java API
Spring Boot 接入大模型实战:通义千问赋能智能应用快速构建
【10月更文挑战第23天】在人工智能(AI)技术飞速发展的今天,大模型如通义千问(阿里云推出的生成式对话引擎)等已成为推动智能应用创新的重要力量。然而,对于许多开发者而言,如何高效、便捷地接入这些大模型并构建出功能丰富的智能应用仍是一个挑战。
94 6
|
1月前
|
监控 Java 应用服务中间件
Spring和Spring Boot的区别
Spring和Spring Boot的主要区别,包括项目配置、开发模式、项目依赖、内嵌服务器和监控管理等方面,强调Spring Boot基于Spring框架,通过约定优于配置、自动配置和快速启动器等特性,简化了Spring应用的开发和部署过程。
50 19
|
1月前
|
Java API Spring
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中拦截器的入门教程和实战项目场景实现的详细指南。
25 0
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
|
1月前
|
Java API Spring
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中过滤器的基础知识和实战项目应用的教程。
23 0
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
|
1月前
|
Java 编译器 Spring
Spring AOP 和 AspectJ 的区别
Spring AOP和AspectJ AOP都是面向切面编程(AOP)的实现,但它们在实现方式、灵活性、依赖性、性能和使用场景等方面存在显著区别。‌
65 2
|
1月前
|
XML 前端开发 Java
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
本文阐述了Spring、Spring Boot和Spring MVC的关系与区别,指出Spring是一个轻量级、一站式、模块化的应用程序开发框架,Spring MVC是Spring的一个子框架,专注于Web应用和网络接口开发,而Spring Boot则是对Spring的封装,用于简化Spring应用的开发。
109 0
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
|
1月前
|
缓存 NoSQL Java
Springboot自定义注解+aop实现redis自动清除缓存功能
通过上述步骤,我们不仅实现了一个高度灵活的缓存管理机制,还保证了代码的整洁与可维护性。自定义注解与AOP的结合,让缓存清除逻辑与业务逻辑分离,便于未来的扩展和修改。这种设计模式非常适合需要频繁更新缓存的应用场景,大大提高了开发效率和系统的响应速度。
58 2