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

过滤器和拦截器都是日常开发中经常使用到的技术,他们都可以对特定的请求进行增强处理,比如在请求之前或之后插入自定义的代码,完成想要的功能。过滤器和拦截器最本质的区别是,过滤器是在请求到达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面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

 需要全套面试笔记的【点击此处即可】免费获取

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工具请求测试

image.png

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

image.png

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

总结

  • 过滤器是在servlet之外执行的,过滤器的代码只会在servlet外层执行
  • 拦截器是基于servlet的处理器handler的,所以拦截器会在控制器处理器这一层执行
  • 过滤器和拦截器的主要区别是执行的时机不同,虽然他们的作用相似,但是在实际开发中,要根据具体的场景,在两者中做出更合适的选择
  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值