如何在SpringBoot项目中使用过滤器和拦截器

简介: 过滤器和拦截器是日常开发中常用技术,用于对特定请求进行增强处理,如插入自定义代码以实现特定功能。过滤器在请求到达 `servlet` 前执行,而拦截器在请求到达 `servlet` 后执行。`SpringBoot` 中的拦截器依赖于 `SpringBoot` 容器,过滤器则由 `servlet` 提供。通过实现 `Filter` 接口并重写 `doFilter()` 方法可实现过滤器;通过实现 `HandlerInterceptor` 接口并重写相应方法可实现拦截器。两者的主要区别在于执行时机的不同,需根据具体场景选择使用。

过滤器和拦截器都是日常开发中经常使用到的技术,他们都可以对特定的请求进行增强处理,比如在请求之前或之后插入自定义的代码,完成想要的功能。过滤器和拦截器最本质的区别是,过滤器是在请求到达servlet之前执行,拦截器则在请求到达servlet之后执行。需要注意的是,SpringBoot中的拦截器依赖于SpringBoot容器,而过滤器是servlet本身提供的。

过滤器的实现

过滤器依赖servlet中的Filter接口,自定义一个Filter的实现类,重写doFilter()方法

java

代码解读

复制代码

@Component
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("hello");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("world");
    }
}

filterChain.doFilter(servletRequest,servletResponse);这个方法的作用是放行请求,在这条语句的前后可以做一些自定义的操作,比如记录日志、定义请求和返回的字符集编码、或者对请求的参数进行处理等。现在过滤器还不能使用,因为SpringBoot的过滤器依赖其提供的过滤器链,所以要先把自定义的过滤器注册到过滤器链中。

java

代码解读

复制代码

@Configuration
public class WebConfig {
    private final MyFilter myFilter;
    @Autowired
    public WebConfig(MyFilter myFilter){
        this.myFilter = myFilter;
    }
    @Bean
    public FilterRegistrationBean<MyFilter> registFilter(){
        FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(myFilter);
        registrationBean.addUrlPatterns("/*");
        registrationBean.setOrder(1);
        return registrationBean;
    }
}

上面的配置类中,我们将MyFilter对象注册到FilterRegistrationBean中,可以理解为通过FilterRegistrationBean将自定义的过滤器注册到了过滤器链中。setOrder(int)的作用是设置过滤器在过滤器链中的执行顺序,直越小顺序越靠前。addUrlPatterns(String... param)方法用来设置要拦截的请求路径。现在请求项目中的任意接口,都会在请求前打印hello,在请求后打印world

拦截器的实现

拦截器是基于SpringBootdispatcherServlet的处理器Handler拦截器实现的,直接上代码

java

代码解读

复制代码

@Component
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("请求前执行");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("返回ModelAndView前执行");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("处理完请求后执行");
    }
}

上面是自定义的拦截器,重写了处理器拦截器接口的preHandlepostHandleafterCompletion方法,分别表示请求前执行返回ModelAndView前执行处理完请求后执行,然后同样的需要将拦截器注册到拦截器链中,代码如下

java

代码解读

复制代码

@Configuration
public class WebConfig implements WebMvcConfigurer {
    private final MyFilter myFilter;
    private final MyInterceptor myInterceptor;

    @Autowired
    public WebConfig(MyFilter myFilter,
                     MyInterceptor myInterceptor){
        this.myFilter = myFilter;
        this.myInterceptor = myInterceptor;
    }
    @Bean
    public FilterRegistrationBean<MyFilter> registFilter(){
        FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(myFilter);
        registrationBean.addUrlPatterns("/*");
        registrationBean.setOrder(1);
        return registrationBean;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor).
                addPathPatterns("/**").order(1);
    }
}

直接沿用了自定义过滤器的配置类,并实现SpringMvc的配置接口WebMvcConfigurer,重写addInterceptors()方法,将我们自定义的拦截器注册到拦截器链中,同样的,也可以使用order()方法设置拦截器的在链中的执行顺序,值越小则优先级越高。addPathPatterns("/**")表示拦截任意请求。

测试拦截器和过滤器

编写一个测试Controller

java

代码解读

复制代码

@RestController
@RequestMapping("/sys")
public class SysUserController {
    @GetMapping(value = "/test")
    public String test() {
        return "200";
    }
}

上面的接口路径既符合过滤器的过滤条件,也符合拦截器的拦截条件,使用postman工具请求测试

控制台打印的数据如下图所示:

可以看到先执行了过滤器的请求前置代码打印了hello,然后过滤器放行后才进入到servlet控制层执行了控制器的前置、中置及后置方法,最后当控制层处理完请求后,最后才执行了过滤器中的请求后置代码打印了world

总结

  • 过滤器是在servlet之外执行的,过滤器的代码只会在servlet外层执行
  • 拦截器是基于servlet的处理器handler的,所以拦截器会在控制器处理器这一层执行
  • 过滤器和拦截器的主要区别是执行的时机不同,虽然他们的作用相似,但是在实际开发中,要根据具体的场景,在两者中做出更合适的选择


转载来源:https://juejin.cn/post/7407621980574990399

相关文章
|
8天前
|
Java 关系型数据库 MySQL
创建一个SpringBoot项目,实现简单的CRUD功能和分页查询
【9月更文挑战第6天】该内容介绍如何使用 Spring Boot 实现具备 CRUD 功能及分页查询的项目。首先通过 Spring Initializr 创建项目并选择所需依赖;其次配置数据库连接,并创建实体类与数据访问层;接着构建服务层处理业务逻辑;最后创建控制器处理 HTTP 请求。分页查询可通过添加 URL 参数实现。
|
17天前
|
XML 前端开发 Java
还不会SpringBoot项目模块分层?来这手把手教你
本文详细介绍了如何为SpringBoot项目创建模块并进行合理的分层设计。通过逐步演示,从创建项目到构建各功能模块,再到具体代码实现,手把手教你实现整洁的代码分层。主要内容包括:创建依赖层、主启动层、模块层及其子模块(如共通层、控制器层、数据持久层等),并通过实例演示了从前端请求到后台服务调用的实际流程。适合SpringBoot初学者及有一定经验但需优化项目结构的开发者参考。
61 2
还不会SpringBoot项目模块分层?来这手把手教你
|
17天前
|
小程序 前端开发 Java
SpringBoot+uniapp+uview打造H5+小程序+APP入门学习的聊天小项目
JavaDog Chat v1.0.0 是一款基于 SpringBoot、MybatisPlus 和 uniapp 的简易聊天软件,兼容 H5、小程序和 APP,提供丰富的注释和简洁代码,适合初学者。主要功能包括登录注册、消息发送、好友管理及群组交流。
40 0
SpringBoot+uniapp+uview打造H5+小程序+APP入门学习的聊天小项目
|
26天前
|
JavaScript 前端开发 Java
SpringBoot + Vue 前端后分离项目精进版本
这篇文章详细介绍了一个基于SpringBoot + Vue的前后端分离项目的搭建过程,包括前端Vue项目的初始化、依赖安装、页面创建和路由配置,以及后端SpringBoot项目的依赖添加、配置文件修改、代码实现和跨域问题的解决,最后展示了项目运行效果。
SpringBoot + Vue 前端后分离项目精进版本
|
17天前
|
小程序 前端开发 JavaScript
【项目实战】SpringBoot+uniapp+uview2打造一个企业黑红名单吐槽小程序
【避坑宝】是一款企业黑红名单吐槽小程序,旨在帮助打工人群体辨别企业优劣。该平台采用SpringBoot+MybatisPlus+uniapp+uview2等技术栈构建,具备丰富的注释与简洁的代码结构,非常适合实战练习与学习。通过小程序搜索“避坑宝”即可体验。
38 0
【项目实战】SpringBoot+uniapp+uview2打造一个企业黑红名单吐槽小程序
|
17天前
|
JavaScript 前端开发 小程序
【项目实战】SpringBoot+vue+iview打造一个极简个人博客系统
这是一个基于 SpringBoot+MybatisPlus+Vue+Iview 技术栈构建的个人极简博客系统,适合初学者实战练习。项目包含文章分类、撰写文章、标签管理和用户管理等功能,代码简洁并配有详细注释,易于上手。此外,该项目也可作为毕业设计的基础进行二次开发。
62 0
【项目实战】SpringBoot+vue+iview打造一个极简个人博客系统
|
25天前
|
安全 Java 关系型数据库
毕设项目&课程设计&毕设项目:基于springboot+jsp实现的健身房管理系统(含教程&源码&数据库数据)
本文介绍了一款基于Spring Boot和JSP技术实现的健身房管理系统。随着健康生活观念的普及,健身房成为日常锻炼的重要场所,高效管理会员信息、课程安排等变得尤为重要。该系统旨在通过简洁的操作界面帮助管理者轻松处理日常运营挑战。技术栈包括:JDK 1.8、Maven 3.6、MySQL 8.0、JSP、Shiro、Spring Boot 2.0等。系统功能覆盖登录、会员管理(如会员列表、充值管理)、教练管理、课程管理、器材管理、物品遗失管理、商品管理及信息统计等多方面。
|
23天前
|
JavaScript Java 关系型数据库
毕设项目&课程设计&毕设项目:基于springboot+vue实现的前后端分离的考试管理系统(含教程&源码&数据库数据)
在数字化时代背景下,本文详细介绍了如何使用Spring Boot框架结合Vue.js技术栈,实现一个前后端分离的考试管理系统。该系统旨在提升考试管理效率,优化用户体验,确保数据安全及可维护性。技术选型包括:Spring Boot 2.0、Vue.js 2.0、Node.js 12.14.0、MySQL 8.0、Element-UI等。系统功能涵盖登录注册、学员考试(包括查看试卷、答题、成绩查询等)、管理员功能(题库管理、试题管理、试卷管理、系统设置等)。
毕设项目&课程设计&毕设项目:基于springboot+vue实现的前后端分离的考试管理系统(含教程&源码&数据库数据)
|
Java Spring 容器
SpringBoot 手写过滤器&加载第三方过滤器
如何手写一个过滤器呢。假设我现在需要一个计时过滤器,我想把每一次调用服务锁花费的时间打印到控制台,我该怎么做呢? 拦截机制有三种: 1. 过滤器(Filter)能拿到http请求,但是拿不到处理请求方法的信息。
2531 0
|
1天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的鲜花商城管理系统
基于Java+Springboot+Vue开发的鲜花商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的鲜花商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
13 2