SpringBoot如何统一规范接口返回值以及统一异常处理

如今SpringBoot框架为我们提供了一个极为方便的搭建微服务项目的方案,但是,在使用SpringBoot进行微服务开发时,我们并不能一上来就写代码(当然,如果一上来就写也没什么问题),我们还应该提前指定一些开发规范,否则代码写到后面会越写越烂,毫无规范可言。

我通过平时的开发,总结了一套关于统一接口返回类型以及统一异常处理的规范,仅供参考。

接口返回值类型规范

如今的后台开发,接口规范基本遵循Restful风格,因此后台往前端传递的数据中往往需要包含如下内容:

  1. 操作是否成功
  2. 状态码
  3. 详细信息
  4. 实体类数据

因此可以规范一个统一的返回实体类ResponseResult,它包含四个成员: boolean success,HttpStatus code,String message,T data,其中code可以自行定义,比如使用整数代替,当然这里使用Spring提供的状态码,不用自己去定义状态码了。

ResponseResult可以如下定义:

public class ResponseResult<T> {
    private boolean success;//是否操作成功
    private HttpStatus code;//操作状态码,rest风格
    private String message;//操作结果详细信息
    private T data;//实体类数据

    public ResponseResult(ResultCode rc) {
        this.success = rc.success();
        this.code = rc.code();
        this.message = rc.message();
    }

    public ResponseResult(ResultCode rc, T data) {
        this.success = rc.success();
        this.code = rc.code();
        this.message = rc.message();
        this.data = data;
    }

	//getter&setter方法
}

将接口的返回值都统一使用这个实体类,这样前台接收数据也就能够进行统一。

由于success,code,message三个属性与实体类data关系不大,且可以通用,我们可以单独拎出来,构造一个枚举,以便通用:

public enum ResultCode {
    ADD_ITEM_SUCCESS(true, HttpStatus.CREATED,"添加商品成功!"),
    NAME_CANNOT_BE_NULL(false, HttpStatus.BAD_REQUEST, "名称不能为空"),
    ;
    //操作是否成功
    boolean success;
    //操作代码
    HttpStatus code;
    //提示信息
    String message;
    private ResultCode(boolean success, HttpStatus code, String message){
        this.success = success;
        this.code = code;
        this.message = message;
    }
	//getter&setter
}

统一异常处理

开发过程中少不了要处理异常,在SpringBoot微服务中可以这样进行异常的统一处理:

Spring帮我们写了一个通知,其原理是Aop,注解为@ControllerAdvice,它能够默认拦截所有带@Controller注解的类,拦截之后可以写增强功能。在类的方法上加上注解@ExceptionHandler(XxxException.class),就能捕获所有指定的异常:

@ControllerAdvice
public class CommonExceptionHandler {

    @ExceptionHandler(MyException.class)
    @ResponseBody
    public ResponseResult<Void> exceptionHandle(MyException e){
        ResultCode rc = e.getExceptionEnum();
        return new ResponseResult<>(rc);
    }
}

这里需要注意的是:CommonExceptionHandler类和Controller类都要能被SpringBoot扫描到!

自定义异常

在代码中想要手动抛出异常,如果不想被try…catch,那么可以自己定义异常,该异常需要包含“是否成功”,“状态码”,“错误信息”,ResultCode刚好包含这三个属性,因此可以直接将ResultCode作为成员:

public class MyException extends RuntimeException{
    private ResultCode resultCode;

    public MyException(ResultCode resultCode) {
        this.resultCode = resultCode;
    }

    public MyException() {
    }

    public ResultCode getExceptionEnum() {
        return resultCode;
    }

    public void setExceptionEnum(ResultCode resultCode) {
        this.resultCode = resultCode;
    }
}

测试

如下是我快速搭好的一个微服务框架:

在这里插入图片描述

controller测试代码:

在这里插入图片描述
service测试代码:

在这里插入图片描述

使用postman工具测试:

正常情况

在这里插入图片描述

异常情况
在这里插入图片描述
代码GitHub链接:https://github.com/ithushuai/exception-demo

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值