springboot中filter、interceptor的区别和实例
前言:从概念上来讲,filter是servlet规范定义的,而interceptor是spring定义的。
作用在什么位置?
一次会话,请求在进入servlet容器执行service()方法之前就会经过filter过滤(上图步骤1),在离开servlet容器相应客户端的时候也会经过过滤器(上图步骤7)。而interceptor,分两种情况,一种是对会话的拦截,需要定义类实现spring的org.springframework.web.servlet.HandlerInterceptor接口并注册到mvc的拦截队列中,其中preHandle()方法在调用Handler之前进行拦截(上图步骤3),postHandle()方法在视图渲染之前调用(上图步骤5.5),afterCompletion()方法在返回相应之前执行(上图步骤6.5);另一种是对方法的拦截,需要使用@Aspect注解,在每次调用指定方法的前、后进行拦截。
下面通过代码详述他们之间的区别:
先写一个controller方法,进行测试。
[code]import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/intercepter") public class InterceptorController { @GetMapping("/pre") public String preHandleTest(){ System.out.println("boom!!!!导弹击中我方指挥部!!"); return "wow"; } }
filter产生的效果
该filter拦截器对上述controller方法进行过滤
[code] import org.springframework.stereotype.Component; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; @Component//注入ioc容器 @WebFilter(filterName = "urlFilter",urlPatterns = "/intercepter/pre")//配置拦截路径 public class UrlFilter implements Filter { //filter初始化的时候调用,即web容器启动时调用 //web容器启动时根据web.xml文件,依次加载ServletContext----》listener---》filter----》servlet @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("【安全过滤雷达已经开启】"); } //filter执行功能,根据参数来看,可以对request,response和chain(是否放行)进行操作 @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("【不明飞行物穿过大气层】");//请求进入servlet之前调用 chain.doFilter(request,response);//请求放行,允许进入servlet,可手动禁止放行 System.out.println("【不明飞行物已经解除警报】");//请求从servlet出来返回客户端之前调用 System.exit(0); } //filter在服务器正常关闭(比如System.exit(0))等情况下会调用。 @Override public void destroy() { System.out.println("【安全过滤雷达已经关闭】"); } }
启动时:
[code]2018-07-19 12:18:51.122 INFO 10428 --- [ost-startStop-1] 【安全过滤雷达已经开启】 2018-07-19 12:18:51.572 INFO 10428 --- [ main]
执行结果:
[code]【不明飞行物穿过大气层】 boom!!!!导弹击中我方指挥部!! 【不明飞行物已经解除警报】
服务器正常关闭:
[code]2018-07-19 12:21:49.042 INFO 6812 --- [ Thread-12] 【安全过滤雷达已经关闭】
interceptor产生的效果
interceptor对请求进行拦截
现在加上interceptor,首先定义interceptor:
[code]package com.peilian.practice.interceptor; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Component public class PreIntercepterDemo implements HandlerInterceptor { //在HandlerMapping获取handler之后,调用handler之前调用该方法,可以对request,response和handler进行操作 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("--------导弹拦截失败!!--------"); return true; } //在调用handler之后,视图渲染之前调用,可以对中request,response,handler,modelAndView进行操作 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("--------司令部被摧毁-----!!!"); } //在视图渲染之后,返回客户端之前调用,可以对request,response,handler以及handler产生的异常信息ex进行操作 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("---------重新开启司令部-------"); } }
然后对interceptor进行注册:
[code] import com.peilian.practice.interceptor.PreIntercepterDemo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @SpringBootConfiguration public class MyWebMvcConfig extends WebMvcConfigurerAdapter { @Autowired private PreIntercepterDemo preIntercepterDemo; @Override public void addInterceptors(InterceptorRegistry registry) { //注册拦截器并配置拦截的路径 registry.addInterceptor(preIntercepterDemo).addPathPatterns("/intercepter/pre"); } }
运行结果:
[code]【不明飞行物穿过大气层】 --------导弹拦截失败!!-------- boom!!!!导弹击中我方指挥部!! --------司令部被摧毁-----!!! ---------重新开启司令部------- 【不明飞行物已经解除警报】
interceptor对方法进行拦截
被拦截的方法:
[code]import org.springframework.stereotype.Component; @Component public class AspectDemo { public void attack(){ System.out.println("》》》攻击《《《"); } }
拦截器定义:
[code]import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Aspect @Component public class EnhanceMonitor { //定义切点 @Pointcut("execution(* com.peilian.*..attack(..))") public void pointCutMethod(){} //前置 @Before("pointCutMethod()") public void magicEnhance1(){ System.out.println("----冰霜特效----"); } //前置 @Before("pointCutMethod()") public void magicEnhance2(){ System.out.println("----火焰特效----"); } //后置 @After("pointCutMethod()") public void afterAttack(){ System.out.println("---攻击后僵直---"); } /*环绕 @Around("pointCutMethod()") public void buffAttack(ProceedingJoinPoint pjp) throws Throwable { System.out.println("----骑士光环---"); pjp.proceed(); System.out.println("-----骑士光环消失----"); }*/ }
运行结果:
[code]----冰霜特效---- ----火焰特效---- 》》》攻击《《《 ---攻击后僵直---
环绕通知开启后,运行结果:
[code]----骑士光环--- ----冰霜特效---- ----火焰特效---- 》》》攻击《《《 -----骑士光环消失---- ---攻击后僵直---
可见,@Around总是在@Before和@After之前运行。另外,还有其他如@AfterReturning和@AfterThrowing,读者请自行百度。
简单总结
过滤器和拦截器在对请求进行拦截时,一个是发生的时机不一样,filter是在servlet容器外,interceptor在servlet容器内,且可以对请求的3个关键步骤进行拦截处理。另外filter在过滤是只能对request和response进行操作,而interceptor可以对request、response、handler、modelAndView、exception进行操作。
如有异议,可至邮 zwh_mc@sina.com,欢迎指正。
阅读更多- spring boot RESTFul API拦截 以及Filter和interceptor 、Aspect区别
- Spring Boot的filter(过滤器)简单使用实例详解
- Spring Boot参考教程(六)Spring Boot配置Servlet,Filter,Listener,Interceptor
- 基于SpringBoot,SSM的Filter,Servlet,Listener,Interceptor的实现
- SpringBoot 自定义filter 和 interceptor,自定义静态文件存放位置
- Spring interceptor vs servlet filter 两者之间的区别
- spring boot (二) servlet listener filter interceptor
- 浅谈:Filter(过滤器)与Interceptor(拦截器)和Spring AOP的区别?
- Servlet 过滤器(filter)和Spring 拦截器(Interceptor)区别
- spring mvc DispatcherServlet详解之interceptor和filter的区别
- springboot(五)filter/interceptor/listener
- Spring Boot 编写Servlet、Filter、Listener、Interceptor的方法
- SpringBoot中的Filter与Interceptor
- spring mvc DispatcherServlet详解之interceptor和filter的区别
- Spring Boot中Servlet&Filter&Listener&Interceptor的使用
- Spring Boot之Filter和Interceptor的对比分析
- java.lang.NoClassDefFoundError: org/springframework/boot/context/embedded/FilterRegistrationBean
- Spring Boot集成Mybatis的实例代码(简洁版)
- SpringMVC的拦截器(Interceptor)和过滤器(Filter)的区别与联系
- SpringMVC框架和spring Boot的区别