package com.vci.starter.web.interceptor; import com.vci.starter.web.constant.TokenKeyConstant; import com.vci.starter.web.util.VciBaseUtil; import com.vci.starter.web.util.WebThreadLocalUtil; import org.apache.commons.lang3.StringUtils; import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.lang.Nullable; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 日志的链路拦截器--所有拦截器之前 * @author weidy * @date 2019/11/7 2:52 PM */ public class VciLogBeforeInterceptor implements HandlerInterceptor { /** * 日志存储的接口 */ @Autowired(required = false) private VciLogStorageI logStorage; /** * 执行拦截 * * @param request 请求对象 * @param response 相应对象 * @param handler 处理器 * @return 是否成功, false表示失败,其他的拦截器将不会执行 * @throws Exception 执行出错时会抛出异常 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //因为拦截器有顺序,所以设置traceId的时候需要在开始就执行 request.setAttribute(TokenKeyConstant.REQUEST_TIMESTAMP,System.currentTimeMillis()); //我们从头部获取看是否有日志的trackId //rpc的框架在其自己的拦截器(或者过滤器)中处理 String traceId = request.getHeader(TokenKeyConstant.LOG_TRACE_ID_KEY); if (StringUtils.isBlank(traceId)) { //为空时,表示这个是浏览器请求的,所以直接生成一个新的ID traceId = VciBaseUtil.getPk(); } MDC.put(TokenKeyConstant.TRACE_ID, traceId); return true; } /** * 拦截器执行完成后 * @param request 请求对象 * @param response 相应对象 * @param handler 处理器 * @param exception 异常 * @throws Exception 执行出错时会抛出异常 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception exception) throws Exception { //这个拦截器结束时还有其他拦截器没有完成。所以这个不清除 String traceId = MDC.get(TokenKeyConstant.TRACE_ID); //删除链路ID MDC.remove(TokenKeyConstant.TRACE_ID); //记录操作日志 String traceIdInRequest = request.getHeader(TokenKeyConstant.LOG_TRACE_ID_KEY); if(StringUtils.isBlank(traceIdInRequest) && logStorage !=null ){ //说明这个不是被服务所请求的,而是通过页面请求的,所以要记录操作日志 logStorage.storageForMvc(traceId,request,response,handler,exception); } } }