项目中需要监听用户具体的请求操作,便通过一个拦截器来监听,并继续相应的日志记录
项目构建与Spring Boot,Spring Boot实现一个拦截器很容易。
Spring Boot的核心启动类继承WebMvcConfigurerAdapter
// 增加拦截器 @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new RequestLog()); } //这个RequestLog就是我们定义的拦截器拦截器的编写
public class RequestLog extends HandlerInterceptorAdapter { /** * 前置检查 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String ip = request.getRemoteAddr(); long startTime = System.currentTimeMillis(); request.setAttribute("requestStartTime", startTime); HandlerMethod handlerMethod = (HandlerMethod) handler; // 获取用户token Method method = handlerMethod.getMethod(); System.out.println("用户:"+ip+",访问目标:"+method.getDeclaringClass().getName() + "." + method.getName()); return true; } // controller处理完成 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); long startTime = (Long) request.getAttribute("requestStartTime"); long endTime = System.currentTimeMillis(); long executeTime = endTime - startTime; // log it if (executeTime > 1000) { System.out.println("[" + method.getDeclaringClass().getName() + "." + method.getName() + "] 执行耗时 : " + executeTime + "ms"); } else { System.out.println("[" + method.getDeclaringClass().getSimpleName() + "." + method.getName() + "] 执行耗时 : " + executeTime + "ms"); } } }我们自己实现的拦截器需要继承HandlerInterceptorAdapter,并重写如下三个方法:
在preHandle中,可以进行编码、安全控制等处理; 在postHandle中,有机会修改ModelAndView;还存在一个也比较重要的方法在afterCompletion中,下面介绍一些这三个方法的执行流程:
发起请求,进入拦截器链,运行所有拦截器的preHandle方法.
当preHandle方法返回false时,从当前拦截器往回执行所有拦截器的afterCompletion方法,再退出拦截器链。
当preHandle方法全为true时,执行下一个拦截器,直到所有拦截器执行完。再运行被拦截的Controller。然后进入拦截器链,运行所有拦截器的postHandle方法,完后从最后一个拦截器往回执行所有拦截器的afterCompletion方法.
当有拦截器抛出异常时,会从当前拦截器往回执行所有拦截器的afterCompletion方法
preHandle方法:返回true,映射处理器执行链将继续执行;当返回false时,DispatcherServlet处理器认为拦截器已经处理完了请求,而不继续执行执行链中的其它拦截器和处理器。