diff --git a/src/main/java/cn/zhangdeman/InitRequestData.java b/src/main/java/cn/zhangdeman/Context.java similarity index 80% rename from src/main/java/cn/zhangdeman/InitRequestData.java rename to src/main/java/cn/zhangdeman/Context.java index 29d5b26..bf5c17a 100644 --- a/src/main/java/cn/zhangdeman/InitRequestData.java +++ b/src/main/java/cn/zhangdeman/Context.java @@ -1,5 +1,6 @@ package cn.zhangdeman; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; @@ -13,7 +14,8 @@ import java.util.Map; // 初始化的请求信息 @Getter @Setter -public class InitRequestData implements Serializable { +@JsonIgnoreProperties(ignoreUnknown = true) // 忽略未知属性字段 +public class Context implements Serializable { @JsonProperty(RecordField.REQUEST_ID) private String requestId; // 本次请求request id @JsonProperty(RecordField.COST) @@ -22,10 +24,6 @@ public class InitRequestData implements Serializable { private String serverIp; // 服务器Ip @JsonProperty(RecordField.SERVER_HOSTNAME) private String serverHostname; // 服务器hostname - @JsonProperty(RecordField.REQUEST_UA) - private String userAgent; // 客户端ua - @JsonProperty(RecordField.REQUEST_CLIENT_IP) - private String clientIp; // 客户端IP @JsonProperty(RecordField.FINISH_TIMESTAMP) private Long finishTimeStamp; // 完成请求时间 @JsonProperty(RecordField.TRACE_ID) @@ -36,6 +34,8 @@ public class InitRequestData implements Serializable { private Map logData; // 本条日志的上下文信息 @JsonProperty(RecordField.RESPONSE_DATA) private Object responseData; // 响应数据 + @JsonProperty(RecordField.REQUEST_INFO) + private Request requestInfo;// 请求信息 // 序列化 @Override @@ -54,9 +54,9 @@ public class InitRequestData implements Serializable { } // 反序列化 - public InitRequestData unserializable(String json) throws JsonProcessingException { + public Context unserializable(String json) throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); - return mapper.readValue(json, new TypeReference() { + return mapper.readValue(json, new TypeReference() { }); } } diff --git a/src/main/java/cn/zhangdeman/RecordField.java b/src/main/java/cn/zhangdeman/RecordField.java index bea7f30..24419f3 100644 --- a/src/main/java/cn/zhangdeman/RecordField.java +++ b/src/main/java/cn/zhangdeman/RecordField.java @@ -12,6 +12,16 @@ public class RecordField { public static final String CONTEXT_DATA = "context_data"; // 本条日志的上下文信息 public static final String RESPONSE_DATA = "response_data"; // 接口响应数据 // 请求信息 - public static final String REQUEST_UA = "request_user_agent"; // 请求ua - public static final String REQUEST_CLIENT_IP = "request_client"; // 请求客户端 + public static final String REQUEST_INFO = "request_info"; // 请求信息 + public static final String REQUEST_UA = "user_agent"; // 请求ua + public static final String REQUEST_CLIENT_IP = "client_ip"; // 请求客户端 + public static final String REQUEST_METHOD = "method"; // 请求方法 + public static final String REQUEST_CONTENT_TYPE = "content_type"; // 请求类型 + public static final String REQUEST_QUERY = "_query"; // query参数 + public static final String REQUEST_BODY = "body"; // body参数 + public static final String REQUEST_HEADER = "header"; // header参数 + public static final String REQUEST_COOKIE = "cookie"; // cookie参数 + public static final String REQUEST_PATH_PARAM = "path_param"; // path参数 + public static final String REQUEST_SIZE = "size"; // 参数大小 + public static final String REQUEST_URI = "uri"; // 请求接口 } diff --git a/src/main/java/cn/zhangdeman/Request.java b/src/main/java/cn/zhangdeman/Request.java new file mode 100644 index 0000000..155fda0 --- /dev/null +++ b/src/main/java/cn/zhangdeman/Request.java @@ -0,0 +1,39 @@ +package cn.zhangdeman; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.servlet.http.HttpServletRequest; +import lombok.Getter; +import lombok.Setter; + +import java.util.Map; + +// 请求相关数据 +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) // 忽略未知属性字段 +public class Request { + @JsonIgnore + HttpServletRequest httpServletRequest;// 原始请求 + @JsonProperty(RecordField.REQUEST_UA) + private String userAgent; // 客户端ua + @JsonProperty(RecordField.REQUEST_CLIENT_IP) + private String clientIp; // 客户端IP + @JsonProperty(RecordField.REQUEST_METHOD) + private String requestMethod; // 请求方法 + @JsonProperty(RecordField.REQUEST_CONTENT_TYPE) + private String requestContentType; // 请求类型 + @JsonProperty(RecordField.REQUEST_QUERY) + private Map requestQuery; // 请求query + @JsonProperty(RecordField.REQUEST_HEADER) + private Map requestHeader; // 请求header + @JsonProperty(RecordField.REQUEST_COOKIE) + private Map requestCookie; // 请求cookie + @JsonProperty(RecordField.REQUEST_PATH_PARAM) + private Map requestPathParam; // path 参数 + @JsonProperty(RecordField.REQUEST_BODY) + private Map requestBody; // 请求body + @JsonProperty(RecordField.REQUEST_URI) + private String requestUri; // 请求接口 +} diff --git a/src/main/java/cn/zhangdeman/RequestInitFilter.java b/src/main/java/cn/zhangdeman/RequestInitFilter.java deleted file mode 100644 index ac61991..0000000 --- a/src/main/java/cn/zhangdeman/RequestInitFilter.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.zhangdeman; - - -import jakarta.servlet.*; -import jakarta.servlet.annotation.WebFilter; -import org.springframework.core.annotation.Order; - -import java.io.IOException; - - -// 初始化请求 -@WebFilter("/*") // 所有接口请求均会触发次过滤器 -@Order(Ordered.REQUEST_ID) // 足够小, 保证最先执行 -public class RequestInitFilter implements Filter { - @Override - public void init(FilterConfig filterConfig) throws ServletException { - } - - @Override - public void destroy() { - } - - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { - InitRequestData initRequestData = new InitRequestData(); - setBaseInfo(initRequestData); // 设置基础信息 - setRequestId(); // 设置请求ID, 每次请求军重新生成 - } - - // 设置基础信息 - private void setBaseInfo(InitRequestData initRequestData) { - initRequestData.setStartTimeStamp(System.currentTimeMillis()); // 开始请求时间 - } - - // 设置请求ID - private void setRequestId() { - } -} diff --git a/src/main/java/cn/zhangdeman/filter/RequestInitFilter.java b/src/main/java/cn/zhangdeman/filter/RequestInitFilter.java new file mode 100644 index 0000000..f48dc9c --- /dev/null +++ b/src/main/java/cn/zhangdeman/filter/RequestInitFilter.java @@ -0,0 +1,111 @@ +package cn.zhangdeman.filter; + + +import cn.zhangdeman.Context; +import cn.zhangdeman.Ordered; +import cn.zhangdeman.Request; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.annotation.WebFilter; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpFilter; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.core.annotation.Order; + +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + + +// 初始化请求 +@WebFilter("/*") // 所有接口请求均会触发次过滤器 +@Order(Ordered.REQUEST_ID) // 足够小, 保证最先执行 +public class RequestInitFilter extends HttpFilter { + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void destroy() { + } + + @Override + public void doFilter(HttpServletRequest httpServletRequest, HttpServletResponse servletResponse, FilterChain filterChain) { + Context context = new Context(); + setBaseInfo(httpServletRequest, context); // 设置基础信息 + setRequestQuery(context.getRequestInfo()); // 设置请求query信息 + setRequestBody(context.getRequestInfo()); // 设置请求Body + setRequestHeaderAndCookie(context.getRequestInfo()); // 填充请求信息: header + cookie + setRequestId(context); // 设置请求ID, 每次请求需要重新生成 + } + + // 设置基础信息 + private void setBaseInfo(HttpServletRequest httpServletRequest, Context context) { + // request 信息 + Request request = new Request(); + request.setHttpServletRequest(httpServletRequest); + request.setClientIp(httpServletRequest.getRemoteAddr()); // client ip + request.setRequestMethod(httpServletRequest.getMethod()); // 请求类型 + request.setRequestContentType(httpServletRequest.getContentType()); // 请求类型 + request.setRequestUri(httpServletRequest.getRequestURI()); // 请求uri + // server 信息 + context.setServerIp(httpServletRequest.getLocalAddr()); // 服务器IP + context.setServerHostname(httpServletRequest.getLocalName()); // 服务器名称 + context.setRequestInfo(request); // 请求信息 + context.setStartTimeStamp(System.currentTimeMillis()); // 开始请求时间 + } + + // 设置请求Query + private void setRequestQuery(Request request) { + Map query = new HashMap<>(); + HttpServletRequest httpServletRequest = request.getHttpServletRequest(); // 原始请求实例 + Map queryParamList = httpServletRequest.getParameterMap(); // query参数列表 + for (Map.Entry entity : queryParamList.entrySet()) { + if (entity.getValue().length == 0) { + // 参数值为空 + query.put(entity.getKey(), ""); + } else { + // 多个参数值, 取第一个 + query.put(entity.getKey(), entity.getValue()[0]); + } + } + request.setRequestQuery(query); + } + + // 设置请求Body + private void setRequestBody(Request request) { + HttpServletRequest httpServletRequest = request.getHttpServletRequest(); // 原始请求实例 + // httpServletRequest.getInputStream() + } + + + // 设置请求信息: header + cookie + private void setRequestHeaderAndCookie(Request request) { + HttpServletRequest httpServletRequest = request.getHttpServletRequest(); // 原始请求实例 + + request.setRequestHeader(new HashMap<>()); // 请求header + request.setRequestCookie(new HashMap<>()); // 请求cookie + // 全部请求header + Enumeration enumeration = httpServletRequest.getHeaderNames(); + while (enumeration.hasMoreElements()) { + String name = enumeration.nextElement(); + if (name.equalsIgnoreCase("cookie")) { + // cookie单独摘出来处理 + continue; + } + String value = httpServletRequest.getHeader(name); + request.getRequestHeader().put(name, value); + } + // 全部请求cookie + Cookie[] cookieList = httpServletRequest.getCookies(); + for (Cookie cookie : cookieList) { + request.getRequestCookie().put(cookie.getName(), cookie.getValue()); + } + } + + // 设置请求ID + private void setRequestId(Context context) { + } +}