本文最后更新于:2023年11月9日 晚上
SpringBoot之统一返回格式与统一异常处理
在任何接口返回数据时,正确的返回格式:
code:状态码 data:数据 message:接口响应信息,一般接口需要的就是这三个数据。
1 2 3 4 5
| { "code": 200, "data": "success", "message": "成功" }
|
但是如果在每一个接口都这样写一个Map返回,或者一个工具类返回,但是这样代码的重复量太复杂。
统一返回的好处:接口返回的东西直接返回,接口的中不用管状态码和响应信息
导入Jar包
1 2 3 4 5 6 7 8 9 10 11 12 13
| <!--Lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> </dependency>
<!--JSON--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.9</version> </dependency>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
@Data public class ResultUtil implements Serializable {
private Integer code;
private String message;
private Object data;
private ResultUtil() {
}
public ResultUtil(ResultCode resultCode, Object data) { this.code = resultCode.code(); this.message = resultCode.message(); this.data = data; }
private void setResultCode(ResultCode resultCode) { this.code = resultCode.code(); this.message = resultCode.message(); }
public static ResultUtil success() { ResultUtil result = new ResultUtil(); result.setResultCode(ResultCode.SUCCESS); return result; }
public static ResultUtil success(Object data) { ResultUtil result = new ResultUtil(); result.setResultCode(ResultCode.SUCCESS); result.setData(data); return result; }
public static ResultUtil fail(Integer code, String message) { ResultUtil result = new ResultUtil(); result.setCode(code); result.setMessage(message); return result; }
public static ResultUtil fail(ResultCode resultCode) { ResultUtil result = new ResultUtil(); result.setResultCode(resultCode); return result; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
public enum ResultCode {
SUCCESS(200, "成功"), PARAM_IS_INVALID(201, "参数无效"), PARAM_IS_BLANK(202, "参数为空"), PARAM_TYPE_BIND_ERROR(401, "参数类型错误"), PARAM_NOT_COMPLETE(402, "参数缺失"), USER_NOTLOGGED_IN(501, "用户未登录"), USER_LOGIN_ERROR(502, "账号不存在或密码错误"), SYSTEM_ERROR(500, "系统异常,请稍后重试");
private Integer code; private String message;
private ResultCode(Integer code, String message) { this.code = code; this.message = message; }
public Integer code() { return this.code; }
public String message() { return this.message; } }
|
配置统一结果返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
@RestControllerAdvice(basePackages = {"com.demo.controller"}) public class ResultResponseAdvice implements ResponseBodyAdvice {
@Override public boolean supports(MethodParameter methodParameter, Class aClass) { return true; }
@Override public Object beforeBodyWrite(Object returnValue, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { ResultUtil result; String returnClassType = returnType.getParameterType().getSimpleName();
if ("void".equals(returnClassType)) { result = ResultUtil.success(); } else if ("Result".equals(returnClassType)) { result = (ResultUtil) returnValue; } else if ("String".equals(returnClassType)) { result = ResultUtil.success(returnValue); return JSON.toJSONString(result); } else { if (Objects.isNull(returnValue)) { result = ResultUtil.success(); } else { result = ResultUtil.success(returnValue); } } return result; } }
|
- 排除NULL字段:在返回时字段为null则不返回 application.yaml文件中
1 2 3
| spring: jackson: default-property-inclusion: NON_NULL
|
配置全局异常处理
@ExceptionHandler 的参数可以是数组,可以有多个异常类。
注:处理异常是会判断异常的继承关系。
比如是 Exception.class 那么就会处理全部的异常,可以把全部异常统一在一个方法处理,也可以分开单独处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
@RestControllerAdvice(basePackages = {"com.demo.controller"}) public class MyExceptionHandler {
@ExceptionHandler({ArithmeticException.class}) private ResultUtil handlerNullPointException() { return ResultUtil.fail(500, " / by zero"); } }
|
效果测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
@RestController public class TestController {
@RequestMapping(path = "/test") public String test() { return "success"; }
@RequestMapping(path = "/testError") public String error() {
int x = 5 / 0;
return "error"; } }
|
自责要短暂,不过要长久铭记。