admin管理员组

文章数量:1794759

spring mvc HandlerInterceptor拦截器

spring mvc HandlerInterceptor拦截器

#spring mvc HandlerInterceptor拦截器

##spring-mvc.xml 配置 在 spring-mvc.xml 文件下增加

<mvc:interceptors> <!—拦截器 拦截器执行顺序:先执行后定义的,排在第一位的最后执行—> <mvc:interceptor> <mvc:mapping path = ““ />//拦截的请求 <bean class = “" />//拦截处理器的全限定名 </mvc:interceptor> <mvc:interceptor> <mvc:mapping path = “” /> //拦截的请求 <bean class = “” >//拦截处理器的权限定名 </mvc:interceptor> </mvc:interceptors>

##定义处理器

拦截处理器 实现 HandlerInterceptor 接口

需要重写三个方法

- public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, object o ) throws Exception // 请求预处理 在请求处理之前进行调用 返回true 才会进入处理器 - public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,Object o,ModelAndView modelAndView) throws Exception // 将在请求处理之后,DispatcherServlet进行视图返回渲染之前进行调用 - public void afterCompletion(HttpServletRequest httpServletRequest, HttpServleResponse httpServletResponse,Object o , Exception e) throws Exception // 整个请求结束之后

##处理器代码

处理器:对接口处理进行计时,如果大于200ms则报警,如果有异常则报警

public class ApiResponseInterceptor extends BaseService implements HandlerInterceptor { private static final ThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<Long>("ThreadLocal StartTime"); @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { long beginTime = System.currentTimeMillis();//1、开始时间 startTimeThreadLocal.set(beginTime); //线程绑定变量(该数据只有当前请求的线程可见) return true; } //TODO 500 报警 @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { logger.error("api通过处理"); } //TODO 判断时间 @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量(开始时间) long endTime = System.currentTimeMillis(); //2、结束时间 long handTime = endTime -beginTime;//时间大于200ms的接口报警 if(handTime > 200){ //发消到报警群 String uri = httpServletRequest.getRequestURI(); logger.info(uri); //线程异步处理 ThreadService service = SpringContextHolder.getBean(ThreadService.class); // service.sendMessage(uri,handTime); } HandlerMethod method = (HandlerMethod)o; logger.info(method.getReturnType().getParameterName()); // HttpServletResponseCopier copier = new HttpServletResponseCopier(httpServletResponse); //copier.getCopy(); //如果出现异常,则进行报警 int status = httpServletResponse.getStatus(); if(status == 500){ //使用线程发送消到钉钉 ThreadService service = SpringContextHolder.getBean(ThreadService.class); service.sendMessageHttpFail(httpServletRequest.getRequestURI()); } } }

由于计时需要在 preHandlehe 和 postHandle 中进行计时,需要声明类变量。由于我们定义的是static,如果需要每个线程都的计时是独立的,那么我们需要使用ThreadLocal。

ThreadLocal 会对对每个线程提供一个变量的副本,变量在线程之间是不共享的(注意是不共享的,)。

This class provides thread-local variables. These variables differ from

  • their normal counterparts in that each thread that accesses one (via its
  • {@code get} or {@code set} method) has its own, independently initialized
  • copy of the variable. {@code ThreadLocal} instances are typically private
  • static fields in classes that wish to associate state with a thread (e.g.,
  • a user ID or Transaction ID).

本文标签: 拦截器springMVCHandlerInterceptor