拦截器(Interceptor)是在SpringMVC中动态拦截控制器方法的执行。
拦截器执行流程:
拦截器与过滤器区别
归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术
拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强
拦截器入门案例
@Component
public class ProjectInterceptor implements HandlerInterceptor {
//handler:被调用的处理器对象,本质上是一个方法对象,对反射技术中的Method对象进行了再包装
//原始方法调用前执行的内容
//返回值类型可以拦截控制的执行,true放行,false终止@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String contentType = request.getHeader("Content-Type");
HandlerMethod hm = (HandlerMethod)handler;
System.out.println("preHandle..."+contentType);
return true;
}@Override
//原始方法调用后执行的内容
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle...");
}@Override
//原始方法调用完成后执行的内容
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {//表现层如果有异常抛出这里可以获取,但我们有统一异常处理,所以这里用得不多
System.out.println("afterCompletion...");
}}
过滤静态资源
@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","/books/*");
}
}
定义配置类,com.xxz.config是上面support所在的位置,这样就把support配置上了:
@Configuration
@ComponentScan({"com.xxz.controller","com.xxz.config"})
@EnableWebMvc
//实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {
@Autowired
private ProjectInterceptor projectInterceptor;
@Autowired
private ProjectInterceptor2 projectInterceptor2;@Override
public void addInterceptors(InterceptorRegistry registry) {
//配置多个拦截器
registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*");
}
}
多个拦截器执行顺序,preHandle返回true时按顺序执行,而其他方法执行是倒序,preHandle返回false则只执行preHandle方法。