Springboot自定义返回格式

参考链接:SpringBoot 如何统一后端返回格式?老鸟们都是这样玩的! - 哔哩哔哩

在Springboot中自定义返回数据的格式。

1.统一返回的格式

其中返回的内容有status状态码、message返回信息、data数据、timestamp时间戳

@Data
public class ResultData<T> {
    /** 结果状态 ,具体状态码参见ResultData.java*/
    private int status;
    private String message;
    private T data;
    private long timestamp ;


    public ResultData (){
        this.timestamp = System.currentTimeMillis();
    }
    
    /*
    *返回的状态码正常
    */

    public static <T> ResultData<T> success(T data) {
        ResultData<T> resultData = new ResultData<>();
        resultData.setStatus(ReturnCode.RC100.getCode());
        resultData.setMessage(ReturnCode.RC100.getMessage());
        resultData.setData(data);
        return resultData;
    }
    /*
    *返回失败则返回对应的状态码和对应的信息
    */
    public static <T> ResultData<T> fail(int code, String message) {
        ResultData<T> resultData = new ResultData<>();
        resultData.setStatus(code);
        resultData.setMessage(message);
        return resultData;
    }

}

返回的status状态码

public enum ReturnCode {
    /**操作成功**/
    RC100(100,"操作成功"),
    /**操作失败**/
    RC999(999,"操作失败"),
    /**服务限流**/
    RC200(200,"服务开启限流保护,请稍后再试!"),
    /**服务降级**/
    RC201(201,"服务开启降级保护,请稍后再试!"),
    /**热点参数限流**/
    RC202(202,"热点参数限流,请稍后再试!"),
    /**系统规则不满足**/
    RC203(203,"系统规则不满足要求,请稍后再试!"),
    /**授权规则不通过**/
    RC204(204,"授权规则不通过,请稍后再试!"),
    /**access_denied**/
    RC403(403,"无访问权限,请联系管理员授予权限"),
    /**access_denied**/
    RC401(401,"匿名用户访问无权限资源时的异常"),
    /**服务异常**/
    RC500(500,"系统异常,请稍后重试"),

    INVALID_TOKEN(2001,"访问令牌不合法"),
    ACCESS_DENIED(2003,"没有权限访问该资源"),
    CLIENT_AUTHENTICATION_FAILED(1001,"客户端认证失败"),
    USERNAME_OR_PASSWORD_ERROR(1002,"用户名或密码错误"),
    UNSUPPORTED_GRANT_TYPE(1003, "不支持的认证模式");



    /**自定义状态码**/
    private final int code;
    /**自定义描述**/
    private final String message;

    ReturnCode(int code, String message){
        this.code = code;
        this.message = message;
    }


    public int getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }
}

完成之后即可返回自定义的格式,但是返回的类型都需要写成ResultData类型,返回结果都需要调用 ResultData.success()这行代码对结果进行包装。

2.借助SpringBoot提供的 ResponseBodyAdvice优化代码

借助SpringBoot提供的 ResponseBodyAdvice优化代码,即不需要返回的类型都需要写成ResultData类型。

ResponseBodyAdvice实现ResponseBodyAdvice接口的两个方法。

原文中ObjectMapper是通过@Autowired自动装配的,我不知道什么原因不可以自动装配。

@RestControllerAdvice
public class ResponeAdvice implements ResponseBodyAdvice<Object> {

    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }
    @SneakyThrows //lombok中的异常处理
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        /*
         如果Controller直接返回String的话,SpringBoot是直接返回,
         故需要通过writeValueAsString方法转换成json
        */
        if(body instanceof String){
            return objectMapper.writeValueAsString(ResultData.success(body));
        }
        /*
         如果返回的结果是ResultData对象,直接返回即可。
        */
        if(body instanceof ResultData){
            return body;
        }
        return ResultData.success(body);
    }
}
3.异常处理

如果返回的状态不是正常的话会出现下面类似的情况

所以需要实现全局异常处理(通过全局处理也可以不用在代码中写try..catch了)

@Slf4j
@RestControllerAdvice
public class RestExceptionHandler {
    /**
     * 默认全局异常处理。
     *
     * @param e the e
     * @return ResultData
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResultData<String> exception(Exception e) {
        log.error("全局异常信息 ex={}", e.getMessage(), e);
        return ResultData.fail(ReturnCode.RC500.getCode(), e.getMessage());
    }
}

其中,@RestControllerAdvice,是RestController的增强类,可用于实现全局异常处理器

@ExceptionHandler,统一处理某一类异常,从而减少代码重复率和复杂度,比如要获取自定义异常可以@ExceptionHandler(BusinessException.class)

@ResponseStatus指定客户端收到的http状态码。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值