SpringBoot 更优雅的实现全局结果包装返回

(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 用来忽略某些方法结果包装。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值