(1)定义 @EnableGlobalResponseBodyHandler注解,用来控制是否启用全局结果包装返回
/**
* @author chenyusheng
* @create 2023/6/28 9:56
* @description 启用结果包装返回
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableGlobalResponseBodyHandler {
}
(2)定义 @IgnoreGlobalResponseBodyHandler 注解,用来忽略结果包装返回
/**
* @author chenyusheng
* @create 2023/6/28 9:56
* @description 忽略返回结果包装
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreGlobalResponseBodyHandler {
}
(3)定义 CommonResult<T> 通用结果包装类
/**
* @param <T>
* @author chenyusheng
* @create 2023/6/28 9:56
* @description 通用结果包装类
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@ApiModel("公共接口返回包装类")
public class CommonResult<T> {
public static final Integer CODE_SUCCESS = StatusCodeEnum.OK.getCode();
/**
* 状态码
*/
@ApiModelProperty("状态码")
private Integer code;
/**
* 消息提示
*/
@ApiModelProperty("消息提示")
private String message;
/**
* 返回数据
*/
@ApiModelProperty("返回数据")
private T data;
/**
* 失败
*
* @param code 状态码
* @param message 消息提示
*/
public static <T> CommonResult<T> error(Integer code, String message) {
return CommonResult.error(code, message, null);
}
/**
* 失败
*
* @param code 状态码
* @param message 消息提示
* @param data 返回数据
* @param <T>
*/
public static <T> CommonResult<T> error(Integer code, String message, T data) {
return CommonResult.<T>builder()
.code(code)
.message(StringUtils.isNotBlank(message) ? message : "执行异常")
.data(data)
.build();
}
/**
* 成功
*
* @param data
* @param <T>
* @return
*/
public static <T> CommonResult<T> success(T data) {
return CommonResult.success("执行成功!", data);
}
/**
* 成功
*
* @param data
* @param <T>
* @return
*/
public static <T> CommonResult<T> success(String message, T data) {
return CommonResult.success(CODE_SUCCESS, message, data);
}
/**
* 成功
*
* @param code
* @param message
* @param data
* @param <T>
* @return
*/
public static <T> CommonResult<T> success(Integer code, String message, T data) {
return CommonResult.<T>builder()
.code(code)
.message(StringUtils.isNotBlank(message) ? message : "执行成功")
.data(data)
.build();
}
}
(4)定义 GlobalResponseBodyHandler 全局结果处理类
/**
* @author chenyusheng
* @create 2023/6/28 9:56
* @description 通过实现 ResponseBodyAdvice 接口,并添加 @ControllerAdvice 接口,拦截 Controller 的返回结果;
* 注意:与 Swagger 集成时,必须配置 basePackages,不然访问 swagger 会报:Unable to infer base url 。。。异常
* 采用 annotations 注解方式,避免这个问题
*/
@Order(1)
@ControllerAdvice(annotations = {EnableGlobalResponseBodyHandler.class})
@SuppressWarnings("all")
public class GlobalResponseBodyHandler implements ResponseBodyAdvice {
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
// 检查忽略注解是否存在
if (returnType.getDeclaringClass().isAnnotationPresent(IgnoreGlobalResponseBodyHandler.class)) {
return false;
}
if (returnType.getMethod().isAnnotationPresent(IgnoreGlobalResponseBodyHandler.class)) {
return false;
}
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
// 如果已经是 CommonResult 类型,则直接返回,非 String 类型,默认会采用 MappingJackson2HttpMessageConverter 转换器
if (body instanceof CommonResult) {
return body;
}
// 如果结果为 String 类型,默认会采用 StringHttpMessageConverter 转换器,直接返回 CommonResult 对象会报错,需要序列化 CommonResult 对象成字符串。
if (body instanceof String) {
return JSONUtil.toJsonStr(CommonResult.success(body));
}
// 如果不是,则包装成 CommonResult 类型
return CommonResult.success(body);
}
}
(5)使用方式
- 在主程序使用 @EnableGlobalResponseBodyHandler 显示启动即可;
- @IgnoreGlobalResponseBodyHandler 用来忽略某些方法结果包装。