Spring Boot 统一返回数据结构以及全局异常处理

前言

看了廖师兄的视频后,结合自己以前的编程经验总结下 :

在 web 开发过程中, 后端要统一返回的数据结构,便于前端处理。例如每个请求,我们都需要知道 :

  1. code : 服务器返回的状态码(主要给程序员看)。例如 : 200 : 请求成功。 500 : 服务器内部错误。
  2. status : 0 或者 1 (用于给前端判断) 。 1 : 处理成功。 0 : 处理失败 。这里要和 code 做区分。status 是逻辑上的错误。例如用户想要删除某一个帖子,用户手滑,连续发了两个请求, 第一个请求成功, 服务器返回 code: 200 , status : 1 。第二个请求成功,但是帖子已经被删除了。因此返回 code : 200 , status : 0 ,msg: “帖子不存在”
  3. msg : 服务器的错误信息 ,主要返回给用户看。
  4. data : 服务器返回的数据。

返回的数据格式如下 :
Spring Boot 统一返回数据结构以及全局异常处理_第1张图片

这样封装的对前端有很多好处,前端可以直接判断,比如 :

	if(status == 1(
	 	...//直接拿 data 里面的数据处理。
	)else {
		// 直接对话框或者 Toast 显示 msg 给用户,客户端不需要再做逻辑判断。
	}

code: 用于前后端撕逼。
例如用户登录服务器返回以下数据 :

Spring Boot 统一返回数据结构以及全局异常处理_第2张图片

客户端只需要判断, status 为 0 , 然后直接给用户显示 msg 即可。
code : 103 为 前端和后端约定好的错误码。 例如 : 103 表示用户账号已被封号。


代码片段

例如接口定义如下 :

    @GetMapping(path = "/user/findAll")
    public BaseResult> findAllUsers() {
        List users = userDao.findAll();
        return ResultUtil.success(users);
    }

BaseResult :

public class BaseResult {

    private Integer code;

    private Integer status;

    private String msg;

    private T data;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

ResultUtil :

public class ResultUtil {


    public static  BaseResult success(T data) {
        return commonResult(1, 200, "请求成功", data);
    }

    public static  BaseResult error(String errorMsg) {
        return error(200, errorMsg);
    }

    public static  BaseResult error(Integer code, String errorMsg) {
        return commonResult(0, code, errorMsg, null);
    }

    private static  BaseResult commonResult(Integer status, Integer code, String errMsg, T data) {
        BaseResult result = new BaseResult<>();
        result.setStatus(status);
        result.setCode(code);
        result.setMsg(errMsg);
        result.setData(data);
        return result;
    }
}

统一的异常处理

Spring Boot 在有异常发生时,默认返回的 Json 数据结构如下 : (用 Postman 测试接口)

{
    "timestamp": "2018-10-20T02:39:20.506+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "No message available",
    "path": "/user/findAll"
}

很明显上面 Json 返回的字段不是我们想要的类型,我们可以处理下。

新建一个 BaseException : 这个异常为服务端主动抛出 , 例如用户没有登录,输入密码错误, 服务器直接抛出该异常,然后交由全局异常处理。

public class BaseException extends RuntimeException {
	// 错误信息
    private String errorMsg;
	// 服务器状态码
    private Integer code;

    public BaseException(String errorMsg) {
        super(errorMsg);
        this.errorMsg = errorMsg;
    }

    public BaseException(Integer code, String errorMsg) {
        super(errorMsg);
        this.errorMsg = errorMsg;
        this.code = code;
    }


    public String getErrorMsg() {
        return errorMsg;
    }

    public Integer getCode() {
        return code;
    }
}

全局捕获异常 :

@ControllerAdvice
public class GlobalExceptionHandle {
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public  BaseResult handle(Exception e) {
        if (e instanceof BaseException) {
            Integer code = 104;
            BaseException exception = (BaseException) e;
            if (exception.getCode() != 0) {
                code = exception.getCode();
            }
            return ResultUtil.error(code, e.getMessage());
        }
        return ResultUtil.error(500, e.getMessage() == null ? "服务器内部错误" : e.getMessage());
    }
}

这里的 104 为 前端和后端约定好的返回码 。

你可能感兴趣的:(Web)