SpringMvc拦截器HandlerInterceptor
SpringMvc拦截器HandlerInterceptor接口
可拦截进入 Controller 层的方法,做进一步处理
应用场景:防重提交、登录校验、日志记录、请求完后释放资源等等
HandlerInterceptor接口中的三个default方法
preHandle
preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
请求进入controller方法之前执行,返回一个布尔值,如果这个值为真,则放行,进入下一个拦截器的
preHandle(如果有多个拦截器的时候),如果系统只有一个拦截器,
为真时,则进入唯一的postHandle方法
postHandle
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView)
postHandle controller方法执行完成后调用(
无异常情况,这里只是代码层面上执行完,响应结果其实还没拿到)。如果controller层方法发生异常,则不调用该方法,直接进入afterCompletion方法善后处理
afterCompletion
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex)
afterCompletion 整个请求处理完毕后进行回调(可理解为视图渲染完成 or 拿到响应数据),一般用于释放和关闭资源,controller层发生异常时,afterCompletion方法也可执行
三个方法执行顺序分析
(只针对一个拦截器)
无异常情况
请求 ==》先来到preHandle,返回true向下执行 ==》对应controller方法体执行,无异常 =》 postHandle =》 afterCompletion =》afterCompletion运行完,前端才能拿到响应
有异常情况
请求 ==》先来到preHandle,返回true向下执行 ==》对应controller方法体执行,有异常 =》发生异常后,不经过postHandle方法,直接跳转到afterCompletion方法 =》afterCompletion运行完,前端才能拿到响应
拦截器代码实现过程
第一:实现
HandlerInterceptor接口
@Slf4j
@Component
public class RepeatSubmitInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// TODO 根据具体的业务逻辑实现控制返回 true / false
return true;
}
@Override
public void postHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) {}
// 方法请求完成后捕获
@Override
public void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
log.info("mosey-afterCompletion");
}
}
第二:编写一个
WebMvcConfigurer配置接口的实现类,重写addInterceptors方法,在方法体中注册第一步中定义的拦截器,使拦截器生效,
@Configuration
public class WebConfig implements WebMvcConfigurer {
// 注入第一步中定义的拦截器
@Autowired private RepeatSubmitInterceptor repeatSubmitInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 可定义一些你不想拦截的uri,注意,这里的路径应该是controller层的全路径,不应该包含application.yml/bootstrap.yml中定义的context-path的路径
final String[] commonExclude = {"/error", "/files/**"};
// 注册第一步中定义的拦截器
registry.addInterceptor(repeatSubmitInterceptor).excludePathPatterns(commonExclude);
}
}
excludePathPatterns注意事项
使用
excludePathPatterns排除不想拦截的URL时候,注意,这里的路径应该是controller层的全路径,不应该包含application.yml/bootstrap.yml中定义的context-path的路径
通配符应该用
**而不是*
当找不到对应的路径时,springmvc会重定向到error路径

浙公网安备 33010602011771号