拦截器
一.拦截器
Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。
拦截器和过滤器
- 拦截器是基于java的反射机制的,而过滤器是基于函数回调。
- 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
- 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
- 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
- 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
- 拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑
二.拦截器的方法介绍
拦截器的方法介绍 HandleInterceptor的三个方法
-
preHandle() ,在请求被处理之前进行调用
- 返回值:是否需要将当前请求拦截下来:false:请求将被终止 ;true:请求会被继续运行
- 参数:HttpServletRequest, HttpServletResponse, Object Object:被拦截的请求目标对象
-
postHandle() ,在请求被处理之后进行调用
- 参数:HttpServletRequest, HttpServletResponse, Object, ModelAndView
- ModelAndView:改变显示的视图(setViewName)或者修改发往视图的方法 (具体可以参考HandleInterceptor接口的源码)
-
afterCompletion() ,在请求结束之后才进行调用
- 作用:做资源的销毁,如关闭IO流
-
afterConcurrentHandlingStarted方法用来处理异步请求。
三.拦截器的使用场景
- 使用原则:处理所有请求的共同问题
- 解决乱码问题
- 解决权限验证问题
四.demo实现(Springboot)
-
拦截器实现
@Component @Slf4j public class TestInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("请求testInterceptor preHandle true"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { log.info("请求testInterceptor postHandle start"); super.postHandle(request, response, handler, modelAndView); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { log.info("请求testInterceptor afterCompletion start"); super.afterCompletion(request, response, handler, ex); } }
-
拦截器配置
//在拦截器配置类class上使用要注解@Configuration,这里要实现接口WebMvcConfigurer @Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private TestInterceptor testInterceptor; //重写addInterceptors方法,这个方法里要配置两项,一个是拦截器,一个是拦截器的URL。 @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(testInterceptor).addPathPatterns("/interceptor_test"); } }
-
控制类
@GetMapping("/interceptor_test") public String testInterceptor(){ log.info("拦截测试Controller方法"); return "拦截测试方法"; }