feat(gateway): 添加全局响应处理器和统一返回结果封装
- 新增 GlobalResponseHandler 类实现全局响应处理 - 添加 Result 类用于统一返回结果封装 - 实现 JsonUtil 工具类用于对象与 JSON 字符串转换 -优化了返回类型为 String 时的处理逻辑
This commit is contained in:
parent
8da7e6a32a
commit
94423833dc
@ -0,0 +1,65 @@
|
|||||||
|
package com.zsc.edu.gateway.framework.response;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.core.MethodParameter;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
|
import org.springframework.http.server.ServerHttpRequest;
|
||||||
|
import org.springframework.http.server.ServerHttpResponse;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应统一封装
|
||||||
|
* <p>
|
||||||
|
* 将响应数据,封装成统一的数据格式。
|
||||||
|
* <p>
|
||||||
|
* 通过本处理器,将接口方法返回的数据,统一封装到 Result 的 data 字段中,如果接口方法返回为 void,则 data 字段的值为 null。
|
||||||
|
*
|
||||||
|
* @author zhuang
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestControllerAdvice(basePackages = "com.example.web")
|
||||||
|
public class GlobalResponseHandler implements ResponseBodyAdvice<Object> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 此组件是否支持给定的控制器方法返回类型和选定的 {@code HttpMessageConverter} 类型。
|
||||||
|
*
|
||||||
|
* @return 如果应该调用 {@link #beforeBodyWrite} ,则为 {@code true};否则为false。
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
|
||||||
|
// 返回类型不为Result,才需要封装
|
||||||
|
return returnType.getParameterType() != Result.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一封装返回响应数据
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
|
||||||
|
Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
|
||||||
|
ServerHttpResponse response) {
|
||||||
|
|
||||||
|
// 数据封装为Result:将接口方法返回的数据,封装到 Result.data 字段中。
|
||||||
|
Result<Object> result = Result.success(body);
|
||||||
|
|
||||||
|
// 返回类型不是 String:直接返回
|
||||||
|
if (returnType.getParameterType() != String.class) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回类型是 String:不能直接返回,需要进行额外处理
|
||||||
|
// 1. 将 Content-Type 设为 application/json ;返回类型是String时,默认 Content-Type = text/plain
|
||||||
|
HttpHeaders headers = response.getHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
// 2. 将 Result 转为 Json字符串 再返回
|
||||||
|
// (否则会报错 java.lang.ClassCastException: com.example.core.model.Result cannot be cast to java.lang.String)
|
||||||
|
return JsonUtil.toJson(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.zsc.edu.gateway.framework.response;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhuang
|
||||||
|
*/
|
||||||
|
public class JsonUtil {
|
||||||
|
|
||||||
|
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将对象转换为 JSON 字符串
|
||||||
|
*
|
||||||
|
* @param obj 需要转换的对象
|
||||||
|
* @return JSON 字符串
|
||||||
|
*/
|
||||||
|
public static String toJson(Object obj) {
|
||||||
|
try {
|
||||||
|
return objectMapper.writeValueAsString(obj);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException("Failed to convert object to JSON", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.zsc.edu.gateway.framework.response;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回响应,统一封装实体
|
||||||
|
*
|
||||||
|
* @param <T> 数据实体泛型
|
||||||
|
* @author zhuang
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
@EqualsAndHashCode
|
||||||
|
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public class Result<T> {
|
||||||
|
|
||||||
|
private String userMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误码<br>
|
||||||
|
* 调用成功时,为 null。<br>
|
||||||
|
* 示例:A0211
|
||||||
|
*/
|
||||||
|
private String errorCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误信息<br>
|
||||||
|
* 调用成功时,为 null。<br>
|
||||||
|
* 示例:"用户输入密码错误次数超限"
|
||||||
|
*/
|
||||||
|
private String errorMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据实体(泛型)<br>
|
||||||
|
* 当接口没有返回数据时,为 null。
|
||||||
|
*/
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
|
||||||
|
public static <T> Result<T> success(T data) {
|
||||||
|
return new Result<>("操作成功!", null, null, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static <T> Result<T> fail(String userMessage, String errorCode, String errorMessage) {
|
||||||
|
return new Result<>(userMessage, errorCode, errorMessage, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user