拦截器概念
动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行
作用:
- 在指定的方法调用前后执行预先设定的代码
- 阻止原始方法的执行
过滤器与拦截器区别
归属不同:过滤器(Filter)属于Servlet技术,拦截器(Interceptor)属于SpringMVC技术
拦截内容不同:过滤器(Filter)对所有访问进行增强,拦截器(Interceptor)仅针对SpringMVC的访问进行增强。
制作拦截器功能类
@Component public class ProjectInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle"); HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion"); HandlerInterceptor.super.afterCompletion(request, response, handler, ex); } }
添加拦截器
在config包下创建SpringMvcSupport
@Configuration public class SpringMvcSupport extends WebMvcConfigurationSupport { @Autowired private ProjectInterceptor projectInterceptor; @Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/pages/**").addResourceLocations("/pages/"); } @Override protected void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(projectInterceptor).addPathPatterns("/books"); } }
此时需要确认SpringMvcConfig中扫描config包
测试运行
可以看出运行顺序为preHandle,controller,postHandle,afterCompletion
若访问http://localhost/books/1,则不会输出
添加拦截器时修改为,则可拦截以/books为开头的请求
@Override protected void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*"); }
正常输出
若在preHandle中,返回值为false
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle"); return false; }
则输出为
说明可以通过设定preHandle的返回值达成拦截效果。
P.S
可以将添加拦截器直接写在SpringMvcConfig中
@Configuration @ComponentScan({"com.rikka.controller"}) @EnableWebMvc public class SpringMvcConfig implements WebMvcConfigurer { @Autowired private ProjectInterceptor projectInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*"); } }
运行测试,依然生效
拦截器参数
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String ans = request.getHeader("Date"); System.out.println("preHandle "+ans); return true; }
测试运行:
成功获取date
前置处理
request:请求对象
reponse:响应对象
handler:被调用的处理器对象,本质上是一个方法对象,对Method对象进行了包装
后置处理
modelAndView:如果处理器执行完成具有返回结果,可以读取到对应数据与页面信息,并进行调整。
完成后处理
ex:如果出现异常对象,可以针对异常情况进行单独处理。
拦截器链
拦截器链的运行顺序参照拦截器添加顺序
public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*"); registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*"); }
运行结果如下:
若第一个拦截器preHandle返回值为false,运行结果如下:
若三个拦截器,在第二个运行时中断,则运行结果如下:
至此,SpringMVC的学习基本告一段落了。