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 用来忽略某些方法结果包装。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
SpringBoot中,可以通过定义一个全局的异常处理器和返回值处理器来实现全局统一返回。 1. 全局异常处理器 在SpringBoot中,可以通过实现`@ControllerAdvice`注解的类来定义一个全局的异常处理器。这个类中的方法可以捕获所有Controller中抛出的异常,并进行统一处理。 示例代码: ```java @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) @ResponseBody public ResultVO handleException(Exception e) { ResultVO resultVO = new ResultVO(); resultVO.setCode(ResultEnum.ERROR.getCode()); resultVO.setMsg(e.getMessage()); return resultVO; } } ``` 在上面的例子中,我们定义了一个`GlobalExceptionHandler`类,并使用`@ControllerAdvice`注解标记它是一个全局异常处理器。在这个类中,我们定义了一个`handleException`方法,它使用`@ExceptionHandler`注解标记它可以处理所有类型的异常。在方法中,我们可以根据异常类型进行不同的处理,并返回一个统一的`ResultVO`对象。 2. 全局返回值处理器 在SpringBoot中,可以通过实现`ResponseBodyAdvice`接口来定义一个全局返回值处理器。这个类中的方法可以对Controller返回的结果进行统一处理。 示例代码: ```java @ControllerAdvice public class GlobalResponseHandler implements ResponseBodyAdvice<Object> { @Override public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) { return true; } @Override public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { ResultVO resultVO = new ResultVO(); resultVO.setCode(ResultEnum.SUCCESS.getCode()); resultVO.setMsg(ResultEnum.SUCCESS.getMsg()); resultVO.setData(o); return resultVO; } } ``` 在上面的例子中,我们定义了一个`GlobalResponseHandler`类,并实现了`ResponseBodyAdvice`接口。在类中,我们实现了`supports`和`beforeBodyWrite`方法。`supports`方法返回`true`表示这个处理器可以处理所有类型的返回值。`beforeBodyWrite`方法对Controller返回的结果进行统一处理,将返回包装成一个统一的`ResultVO`对象。 通过定义全局异常处理器和返回值处理器可以实现全局统一返回,统一格式的返回值可以方便前端调用和处理。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值