拦截器(Interceptor)
拦截器(Interceptor)是spring中的概念,相对于过滤器而言,控制的更加细节。
一:拦截器可以在三个地方进行执行:
1、在controller之前,通过拦截器执行一段代码。
2、在controller之后,通过拦截器执行一段代码,此时只是controller执行完毕,视图还没开始渲染。
3、在整个请求结束的时候,还可以通过拦截器执行一段代码。
二:拦截器的应用场景:
拦截器的本质是面向切面编程(AOP),符合横切关注点的功能都可以放在拦截器中来实现,主要的应用场景包括:
1、登录验证,判断用户是否登录。
2、权限验证,判断用户是否有权限访问资源,如校验token。
3、日志记录,记录请求操作日志(用户IP,访问时间等),以便统计请求访问量。
4、处理cookie,本地化、国际化、主题等。
5、性能监控,监控请求处理时长等。
三:使用拦截器的方法:
1、创建支持它的@Component类,它应该实现HandlerInterceptor接口。
2、实现WebMvcConfigurer配置器,注册到spring容器中,添加拦截路径和放行路径。
/**
* 自定义拦截器
*/
@Component
public class InterceptorBean implements HandlerInterceptor {
//进入controller之前执行的
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("已进入拦截器");
return HandlerInterceptor.super.preHandle(request, response, handler);
}
//进入controller之后执行的
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("控制器controller执行完毕");
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
//整个拦截器执行之后执行(请求结果之后执行的)
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("得到返回结果:"+response);
System.out.println("请求完毕");
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
/**
* 注入适配器并设置拦截路径
*/
@Configurable
public class InterceptorConfig implements WebMvcConfigurer {
//注入自定义拦截器
@Autowired
InterceptorBean interceptorBean;
//给自定义添加拦截规则(多个拦截器时,先定义先执行;还可以通过order方法设置执行顺序,值越小越先执行)
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptorBean)
.addPathPatterns("/**")
.excludePathPatterns("/**/LoginController/**/", "/**/error")//放行路径
.excludePathPatterns("/error");
// 可以添加多个自定义拦截器
// registry.addInterceptor(interceptorBean2)
// .addPathPatterns("/**")
// .excludePathPatterns("/**/LoginController/**/", "/**/error")//放行
// .excludePathPatterns("/error505");
WebMvcConfigurer.super.addInterceptors(registry);
}
}
四:拦截器和过滤器的区别:
1、过滤器只能在容器初始化时被调用一次,在action的生命周期中,而拦截器可以在多次被调用。
2、过滤器可以对几乎所有的请求起作用,拦截器只能对action请求起作用。
3、过滤器不能访问action上下文、堆栈里的对象,而拦截器可以访问。
4、过滤器依赖于servlet容器,而拦截器不依赖于servlet容器。
5、过滤器基于函数回调,而拦截器是基于Java的反射机制。
6、过滤器不能获取IOC容器中的各个bean,而拦截器可以,这点很重要,而拦截器中注入一个service可以调用业务逻辑。
五、拦截器和过滤器的执行顺序:
拦截器是在DispatcherServlet这个servlet中执行的,因此所有的请求最先进入Filter,最后离开Filter。
Filter ——>Interceptor.preHandle——>Handle——>Interceptor.postHandle——>Interceptor.afterCompletion——>Filter