dangsn
2024-06-11 b6dee87c91bfdcb68fcc456c9a2ec46b2ed7cbe3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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);
        }
    }
}