一般用法
项目中最常见到的是封装一个工具类,类中定义需要返回的字段信息,把需要返回前端的接口信息,通过该类进行封装,这样就可以解决返回格式不统一的现象了。
public enum ResultMsgEnum {
SUCCESS(0, "成功"),
FAIL(-1, "失败"),
AUTH_ERROR(502, "授权失败!"),
SERVER_BUSY(503, "服务器正忙,请稍后再试!");
private int code;
private String message;
ResultMsgEnum(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return this.code;
}
public String getMessage() {
return this.message;
}
}
public class Result {
private int code;
private String message;
private T data;
public Result() {
}
public Result(int code, String message) {
this.code = code;
this.message = message;
}
/**
* 成功
*/
public static Result success(T data) {
Result result = new Result();
result.setCode(ResultMsgEnum.SUCCESS.getCode());
result.setMessage(ResultMsgEnum.SUCCESS.getMessage());
result.setData(data);
return result;
}
/**
* 失败
*/
public static Result error(int code, String message) {
return new Result(code, message);
}
}
调用示例
@RequestMapping("/loginSuccess")
@ResponseBody
public Result loginSuccess() {
HashMap
{
"code": 0,
"message": "成功",
"data": {
"user": "zhangsan"
}
}
@RequestMapping("/loginError")
@ResponseBody
public Result loginError() {
HashMap
{
"timestamp": "2021-12-10T06:11:05.159+00:00",
"status": 500,
"error": "Internal Server Error",
"path": "/basic/loginError"
}
通过上面两个例子,我们发现当程序正常返回时已经没有问题了,但是当程序发生异常时,返回的格式很不友好。不处理好这些事情,会严重影响自己在前端小姐姐心中的高大形象的,这是决不能容忍的。
进阶用法
解决这个问题需要两步:
- 自定义返回数据,统一封装数据返回格式
ResponseBodyAdvice: 该接口是SpringMVC 4.1提供的,它允许在 执行 @ResponseBody后自定义返回数据,用来封装统一数据格式返回; - 全局捕获抛出的异常
@RestControllerAdvice: 该注解是对Controller进行增强的,可以全局捕获抛出的异常。
show code
@RestControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice
@RestControllerAdvice
@Slf4j
public class CustomerExceptionHandler {
/**
* 自定义异常处理 ServerBusyException
*/
@ExceptionHandler(ServerBusyException.class)
public String ErrorHandler(ServerBusyException e) {
log.error("服务器正忙,请稍后再试!!", e);
return Result.error(ResultMsgEnum.SERVER_BUSY.getCode(),ResultMsgEnum.SERVER_BUSY.getMessage());
}
/**
* 统一未知异常处理
*/
@ExceptionHandler(Exception.class)
public Result Execption(Exception e) {
log.error("未知异常!", e);
return Result.error(ResultMsgEnum.FAIL.getCode(),ResultMsgEnum.FAIL.getMessage());
}
}
测试代码如下:
@RequestMapping("/loginSuccess")
@ResponseBody
public String loginSuccess() {
return "hello world!";
}
返回值:
{"code":0,"message":"成功","data":"hello world!"}
@RequestMapping("/loginSuccessMap")
@ResponseBody
public Map loginSuccessMap() {
Map map = new HashMap();
map.put("user", "zhangsan");
return map;
}
返回值:
{
"code": 0,
"message": "成功",
"data": {
"user": "zhangsan"
}
}
@RequestMapping("/loginError")
@ResponseBody
public Map loginError() {
HashMap
总结
本文主要就两个类的配置,即处理统一返回结果的类ResponseAdvice和异常处理类CustomerExceptionHandle。全文围绕RestControllerAdvice、ResponseBodyAdvice的使用,通过一步步的迭代,最终构建一套通用的代码代码返回格式。
参考原文:https://zhuanlan.zhihu.com/p/438433774