互联网公司中,后端通常都会拆分成多个独立的微服务,这时候就会涉及每个服务返回给前端的数据格式不统一问题。下面就来实现一个比较常用的数据格式,统一所有服务的返回值格式。
一般响应的数据格式包括如下几个部分:
{
"code": 200,//响应编码
"message": "SUCCESS",//响应文本信息
"data": {//接口返回值
"name": "zhangsan",
"age": 16,
"sex": 男
}
}
对于异常处理情况,如果我们在controller中通过try catch来处理异常的话,Controller层每个接口都有try catch代码块,代码会变的很冗余。下面我们就通过spring boot的注解来省略掉controller中的try-catch 帮助我们来封装异常信息并返回给前端,这样用户也不会得到一些奇奇怪怪的错误提示。
@data
@AllArgsConstructor
public class ResponseMessage<T> {
//响应编码
private int code;
//响应文本信息
private String message;
//接口返回值
private T data;
}
public enum ResponseStatus{
SUCCESS(200, "成功"),
METHODFAIL(500, "ENCOUNTER AN ERROR WHEN EXECUTE METHOD"),
UNKNOWEXCEPTION(3000, "THIS IS AN UNKNOW EXCEPTION");
private int code;
private String message;
ResponseStatus(int code, String message){
this.code = code;
this.message= message;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}
在业务层总会因为某些原因,需要手动抛出异常,响应给前端,提示用户。一般这种异常不建议直接使用RuntimeException,一般会手动创建自己的异常类,并继承RuntimeException。
public class BusinessRuntimeException extends RuntimeException {
public BusinessRuntimeException (String message){
super(message);
}
}
@RestControllerAdvice都是对Controller进行增强的,可以全局捕获spring mvc抛的异常。
@ExceptionHandler(value = Exception.class)
ExceptionHandler的作用是用来捕获指定的异常。
@RestControllerAdvice(annotations = RestController.class)
public class OverAllExceptionAdvice<T> {
public ResponseMessage sendSuccessResponse(){
return new ResponseMessage(ResponseStatus.SUCCESS.getCode(),ResponseStatus.SUCCESS.getMessage(), null);
}
public ResponseMessage sendSuccessResponse(T data) {
return new ResponseMessage(ResponseStatus.SUCCESS.getCode(),ResponseStatus.SUCCESS.getMessage(), data);
}
@ExceptionHandler(BusinessRuntimeException.class)
public ResponseMessage sendErrorResponse_UserDefined(Exception exception){
return new ResponseMessage(ResponseStatus.METHODFAIL.getCode(),((BusinessRuntimeException )exception).getMessage(), null);
}
@ExceptionHandler(Exception.class)
public ResponseMessage sendErrorResponse_System(Exception exception){
if (exception instanceof BusinessRuntimeException) {
return this.sendErrorResponse_UserDefined(exception);
}
return new ResponseMessage(ResponseStatus.UNKNOWEXCEPTION.getCode(),ResponseStatus.UNKNOWEXCEPTION.getMessage(), null);
}
}
通过上面的一波操作,我们的controller中就不需要再去写大量的try-catch了,RestControllerAdvice会自动帮助catch,并匹配相应的ExceptionHandler,然后重新封装异常信息,返回值,统一格式返回给前端。
@GetMapping("/doObject")
public CallResultMsg testObjectReturn(){
Map<String, Integer> map = new HashMap();
map.put("张三", 19);
map.put("李四", 29);
map.put("王五", 30);
return new OverAllExceptionAdvice<Map>().sendSuccessResponse(map);
}
@GetMapping("/doException/{x}")
public int testExceptionResturn(@PathVariable int x){
if (0 < x && x < 10){
throw new BusinessRuntimeException (ResponseStatus.METHODFAIL.getMessage());
} else {
return 1/0;
}
}
执行结果:
{
"code": 200,
"message": "SUCCESS",
"data": {
"张三": 19,
"李四": 29,
"王五": 30
}
}
{
"code": 500,
"message": "ENCOUNTER AN ERROR WHEN EXECUTE METHOD ",
"data": null
}