在Spring中使用拦截器非常简单,但是之前一直没有关注过第三个参数Object handler。
官方API中是这么定义的:
SpringMVC会将请求通过处理器映射器将请求交给匹配的Handler处理,这个handler参数就是描述的处理请求的Handler。
下面定义了一个拦截器:
/**
* @author Dongguabai
* @date 2018-07-01 13:30
*/
@Slf4j
public class HttpInterceptor implements HandlerInterceptor{
/**
* 在请求处理之前进行调用(Controller方法调用之前)
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//如果是SpringMVC请求
if(handler instanceof HandlerMethod){
HandlerMethod handlerMethod = (HandlerMethod) handler;
log.info("当前拦截的方法为:{}",handlerMethod.getMethod().getName());
log.info("当前拦截的方法参数长度为:{}",handlerMethod.getMethod().getParameters().length);
log.info("当前拦截的方法为:{}",handlerMethod.getBean().getClass().getName());
System.out.println("开始拦截---------");
String uri = request.getRequestURI();
System.out.println("拦截的uri:"+uri);
}
return true;
}
/**
* 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后),不一定会触发
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
System.out.println("请求完成后---------");
}
/**
* 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行
* (主要是用于进行资源清理工作),肯定会触发
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
log.info("Exception:{}",ex);
}
}
在MVC中注册:
启动程序,访问:
输出结果:
发现可以通过这个handler获取映射方法的参数。
那么如果执行的方法中抛出异常了呢,再来测试下:
访问这个方法必然会出错因为@CacheEvict注解要使用方法的参数作为key,但是方法并没有参数。
访问测试看看:
但是发现明明出现了异常但是ex仍然为空,这是什么原因呢。
因为我配置了全局异常处理:
异常在这里被捕获到了,具体的异常捕获顺序可以参看我的这篇博客:Spring/SpringBoot中的拦截顺序(异常抛出顺序)