- 拦截器的定义
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 MyHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("--------------拦截器A进行preHandle拦截--------------");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("--------------拦截器A进行postHandle拦截--------------");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("--------------拦截器A进行afterCompletion拦截--------------");
}
}
可以复制实现多个拦截器,执行顺序按照配置文件的配置顺序进行执行
- 拦截器的配置
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private MyHandlerInterceptor myHandlerInterceptor;
@Autowired
private MyHandlerInterceptorB myHandlerInterceptorB;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myHandlerInterceptor).addPathPatterns("/*");
registry.addInterceptor(myHandlerInterceptorB).addPathPatterns("/**");
}
}
ConfigApplication不许需要加格外的注释
-
拦截器和过滤器的执行顺序
-
两个拦截器的执行顺序
上述为所有拦截器均正常通行(preHandle方法return true),当preHandle方法return false时,执行结果如下: -
拦截器A的preHandle为FALSE:
-
拦截器B的preHandle为FALSE:
原因如下:
- 拦截器A放行,拦截器B的preHandle才会执行。
- 拦截器B的preHandle不放行,拦截器B的postHandle和afterCompletion都不会执行。
- 只要有一个拦截器不放行,postHandle不会执行。
特别的是afterCompletion,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion。
拦截器总结
- 在preHandler中return false,则postHandle、afterCompletion都不会执行
- 在handler中抛出异常,则afterCompletion会执行,postHandle不执行(无论是否有ExceptionHandler)
- 正常运行,则postHandle、afterCompletion两个方法都会执行
- 拦截器核心:ThreadLocal。主要作用:实现本地线程内实现数据共享.并且是线程安全的
拦截器的适配器
有时候我们可能只需要实现三个回调方法中的某一个,如果实现HandlerInterceptor接口的话,三个方法必须实现,不管你需不需要,此时spring提供了一个HandlerInterceptorAdapter适配器(一种适配器设计模式的实现),允许我们只实现需要的回调方法。