SpringBoot统一返回结果

SpringBoot统一返回结果

在实际开发中,为了降低开发人员之间的沟通成本,一般返回结果会定义成一个统一格式,具体的格式根据实际开发业务不同有所区别,但至少包括三要素:

  • code状态码:由后端统一定义各种返回结果的状态码
  • message 描述:本次接口调用的结果描述
  • data 数据:本次返回的数据。
{
	"code": 200,
	"msg": "操作成功",
	"data": "Hello World,test123",
}

1 基础实现方式

1.1 定义状态码
public enum ReturnCode {
    RC200(200, "操作成功"),
    RC500(500, "操作失败");

    // 自定义状态码
    private final int code;

    // 自定义描述
    private final String msg;

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

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}
1.2 定义返回对象
@Data
public class ResultData<T> {

    // 结果状态码
    private int code;

    // 响应信息
    private String msg;

    // 响应数据
    private T data;

    // 接口请求时间
    private long timestamp ;

    public ResultData (){
        this.timestamp = System.currentTimeMillis();
    }

    public static <T> ResultData<T> success(T data){
        ResultData resultData = new ResultData();
        resultData.setCode(ReturnCode.RC200.getCode());
        resultData.setMsg(ReturnCode.RC200.getMsg());
        resultData.setData(data);
        return  resultData;
    }

    public static <T> ResultData<T> fail(int code, String msg){
        ResultData resultData = new ResultData();
        resultData.setCode(code);
        resultData.setMsg(msg);
        return resultData;
    }
}
1.3 统一返回格式
	@GetMapping("/getTest")
    public ResultData<String> getTest(){
        return ResultData.success("Hello world!");
    }

返回结果如下所示:

{
	"code": 200,
	"msg": "操作成功",
	"data": "Hello world!",
	"timestamp": 1639013414924
}

到这里,一个统一格式的返回结果已经实现,接口的返回类型为ResultData,但每写一个接口,就要调用ResultData.success()对结果进行包装,重复劳动,浪费体力,所以这个在实际工作中一般用的比较少。

2 高级实现方式

我们只需要借助SpringBoot 提供的ResponseBodyAdvice即可。

**ResponseBodyAdvice的作用:**拦截Controller方法的返回值,统一处理返回值/响应体,一般用来统一返回格式,加解密,签名等等。

2.1 ResponseBodyAdvice返回
@RestControllerAdvice(basePackages = "com.asxy.demo")
public class ResponseAdvice implements ResponseBodyAdvice {

    @Autowired
    private ObjectMapper objectMapper;
    
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        
        if(body instanceof String){	// 如果Controller直接返回String的话,SpringBoot是直接返回,故我们需要手动转换成json。
            return objectMapper.writeValueAsString(ResultData.success(body));
        }
        if(body instanceof ResultData){	// 如果返回的结果是ResultData对象,直接返回即可。
            return body;
        }
        return ResultData.success(body);
    }
}
2.2 全局异常处理器
@Slf4j
@RestControllerAdvice
public class RestExceptionHandler {

    @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());
    }
}
  1. @RestControllerAdvice,RestController的增强类,可用于实现全局异常处理器
  2. @ExceptionHandler,统一处理某一类异常,从而减少代码重复率和复杂度,比如要获取自定义异常可以 @ExceptionHandler(BusinessException.class)
  3. @ResponseStatus指定客户端收到的http状态码
2.3 体验效果
    @GetMapping("/wrong")
    public int error(){
        int i = 9/0;
        return i;
    }

返回结果如下:

{
	"code": 500,
	"msg": "/ by zero",
	"data": null,
	"timestamp": 1639014045820
}
  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值