升级Response

This commit is contained in:
白茶清欢 2025-06-06 22:25:14 +08:00
parent ed6a9a5d78
commit 72b4a4023f
2 changed files with 87 additions and 14 deletions

View File

@ -1,12 +1,15 @@
package cn.zhangdeman.context;
import cn.zhangdeman.consts.RecordField;
import cn.zhangdeman.exception.CustomException;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Getter;
import lombok.Setter;
import org.springframework.http.HttpStatus;
import java.util.HashMap;
import java.util.Map;
@ -15,7 +18,7 @@ import java.util.Map;
@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true) // 忽略未知属性字段
public class Response {
public class Response<Data> {
@JsonProperty(RecordField.REQUEST_ID)
private String requestId; // 本次请求request id
@JsonProperty(RecordField.TRACE_ID)
@ -27,17 +30,25 @@ public class Response {
@JsonProperty(RecordField.RESPONSE_MESSAGE)
private String message; // 响应消息
@JsonProperty(RecordField.RESPONSE_DATA)
private Object data; // 响应数据
private Data data; // 响应数据
@JsonProperty(RecordField.RESPONSE_ERROR_DETAIL)
private Object errorDetail; // 异常详情
@JsonProperty(RecordField.RESPONSE_HTTP_CODE)
private Integer httpCode = 200; // 响应http状态码
private HttpStatus httpCode = HttpStatus.OK; // 响应http状态码, 默认 200
@JsonProperty(RecordField.RESPONSE_HEADER)
private Map<String, String> header; // 响应头
@JsonProperty(RecordField.RESPONSE_COOKIE)
private Map<String, String> cookie; // 响应cookie
@JsonIgnore
private HttpServletResponse httpServletResponse; // 响应实例
private RuntimeContext runtimeContext;
// 响应实例
public Response(RuntimeContext runtimeContext) {
this.runtimeContext = runtimeContext;
setTraceId(runtimeContext.getTraceId());
setRequestId(runtimeContext.getRequestId());
setCost(System.currentTimeMillis() - runtimeContext.getStartTimeStamp()); // 耗时, 毫秒
}
public void addHeader(String key, String value) {
if (null == this.header) {
@ -52,4 +63,69 @@ public class Response {
}
this.cookie.put(key, value);
}
// 设置响应的header与cookie
private void setResponseHeaderAndCookie() {
// 设置header
if (null != getHeader()) {
// 处理header
for (Map.Entry<String, String> headerInfo: getHeader().entrySet()) {
runtimeContext.getHttpServletResponse().addHeader(headerInfo.getKey(), headerInfo.getValue());
}
}
// 设置cookie
if (null != getCookie()) {
// 处理header
for (Map.Entry<String, String> cookieInfo: getCookie().entrySet()) {
runtimeContext.getHttpServletResponse().addCookie(new Cookie(cookieInfo.getKey(), cookieInfo.getValue()));
}
}
// 设置响应状态码
runtimeContext.getHttpServletResponse().setStatus(getHttpCode().value());
}
// 请求成功, 200 状态码
public Response<Data> success(Data data) {
return success(HttpStatus.OK, data);
}
// 请求成功, 自定义http状态码
public Response<Data> success(HttpStatus httpStatus, Data data) {
if (null == getCode()) {
setCode("0");
}
if (null == message) {
setMessage("请求成功");
}
return any(httpStatus, getCode(), getMessage(), data);
}
// 请求失败, 返回200
public Response<Data> failure(String code, String message, Object errorDetail) {
return failure(HttpStatus.OK, code, message, errorDetail);
}
public Response<Data> failure(HttpStatus httpStatus, String code, String message, Object errorDetail) {
setErrorDetail(errorDetail);
return any(httpStatus, code, message, null);
}
public Response<Data> failure(CustomException customException) {
return failure(HttpStatus.OK, customException);
}
public Response<Data> failure(HttpStatus httpStatus, CustomException customException) {
setErrorDetail(customException.getStackTrace()); // 异常堆栈
return any(httpStatus, customException.getCode(), customException.getMessage(), null);
}
// 任意姿势的响应
public Response<Data> any(HttpStatus httpStatus, String code, String message, Data data) {
setHttpCode(httpStatus);
setCode(code);
setMessage(message);
setData(data);
setResponseHeaderAndCookie();
return this;
}
}

View File

@ -1,11 +1,14 @@
package cn.zhangdeman.context;
import cn.zhangdeman.consts.RecordField;
import com.fasterxml.jackson.annotation.JsonIgnore;
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;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Getter;
import lombok.Setter;
@ -19,24 +22,18 @@ import java.util.Map;
public class RuntimeContext implements Serializable {
@JsonProperty(RecordField.REQUEST_ID)
private String requestId; // 本次请求request id
@JsonProperty(RecordField.COST)
private Long cost; // 请求耗时
@JsonProperty(RecordField.SERVER_IP)
private String serverIp; // 服务器Ip
@JsonProperty(RecordField.SERVER_HOSTNAME)
private String serverHostname; // 服务器hostname
@JsonProperty(RecordField.FINISH_TIMESTAMP)
private Long finishTimeStamp; // 完成请求时间
@JsonProperty(RecordField.TRACE_ID)
private String traceId; // 全局trace id
@JsonProperty(RecordField.START_TIMESTAMP)
private Long startTimeStamp; // 开始请求时间
@JsonProperty(RecordField.CONTEXT_DATA)
private Map<String, Object> logData; // 本条日志的上下文信息
@JsonProperty(RecordField.REQUEST_INFO)
private Request requestInfo;// 请求信息
@JsonProperty(RecordField.RESPONSE_INFO)
private Response responseInfo; // 响应信息
@JsonIgnore
private HttpServletRequest httpServletRequest;// 请求实例
@JsonIgnore
private HttpServletResponse httpServletResponse; // 相应实例
// 序列化
@Override