只需一步,在Spring Boot中统一Restful API返回值格式与统一处理异常

开发 后端
在前后端分离大行其道的今天,有一个统一的返回值格式不仅能使我们的接口看起来更漂亮,而且还可以使前端可以统一处理很多东西,避免很多问题的产生。

 

统一返回值

在前后端分离大行其道的今天,有一个统一的返回值格式不仅能使我们的接口看起来更漂亮,而且还可以使前端可以统一处理很多东西,避免很多问题的产生。

比较通用的返回值格式如下: 

  1. public class Result<T> {  
  2.     // 接口调用成功或者失败  
  3.     private Integer code = 0 
  4.     // 失败的具体code  
  5.     private String errorCode = "" 
  6.     // 需要传递的信息,例如错误信息  
  7.     private String msg;  
  8.     // 需要传递的数据  
  9.     private T data;  
  10.     ...  

最原始的接口如下:   

  1. @GetMapping("/test")  
  2.     public User test() {  
  3.         return new User();  
  4.     } 

当我们需要统一返回值时,可能会使用这样一个办法: 

  1. @GetMapping("/test")  
  2.   public Result test() {  
  3.       return Result.success(new User());  
  4.   } 

这个方法确实达到了统一接口返回值的目的,但是却有几个新问题诞生了:

  •  接口返回值不明显,不能一眼看出来该接口的返回值。
  •  每一个接口都需要增加额外的代码量。

所幸Spring Boot已经为我们提供了更好的解决办法,只需要在项目中加上以下代码,就可以无感知的为我们统一全局返回值。 

  1. /**  
  2.  * 全局返回值统一封装  
  3.  */  
  4. @EnableWebMvc  
  5. @Configuration  
  6. public class GlobalReturnConfig {  
  7.     @RestControllerAdvice  
  8.     static class ResultResponseAdvice implements ResponseBodyAdvice<Object> {  
  9.         @Override  
  10.         public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {  
  11.             return true;  
  12.         }  
  13.         @Override  
  14.         public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { 
  15.              if (body instanceof Result) {  
  16.                 return body;  
  17.             }  
  18.             return new Result(body);  
  19.         }  
  20.     }  

而我们的接口只需要写成最原始的样子就行了。 

  1. @GetMapping("/test")  
  2.  public User test() {  
  3.      return new User();  
  4.  } 

统一处理异常

将返回值统一封装时我们没有考虑当接口抛出异常的情况。当接口抛出异常时让用户直接看到服务端的异常肯定是不够友好的,而我们也不可能每一个接口都去try/catch进行处理,此时只需要使用@ExceptionHandler注解即可无感知的全局统一处理异常。 

  1. @RestControllerAdvice  
  2. public class GlobalExceptionHandler {  
  3.     private static final Logger LOG = LoggerFactory.getLogger(GlobalExceptionHandler.class);  
  4.     /**  
  5.      * 全局异常处理  
  6.      */  
  7.     @ExceptionHandler  
  8.     public JsonData handleException(HttpServletRequest request, HttpServletResponse response, final Exception e) {  
  9.         LOG.error(e.getMessage(), e);  
  10.         if (e instanceof AlertException) {//可以在前端Alert的异常  
  11.             if (((AlertException) e).getRetCode() != null) {//预定义异常  
  12.                 return new Result(((AlertException) e).getRetCode());  
  13.             } else {  
  14.                 return new Result(1, e.getMessage() != null ? e.getMessage() : "");  
  15.             }  
  16.         } else {//其它异常  
  17.             if (Util.isProduct()) {//如果是正式环境,统一提示  
  18.                 return new Result(RetCode.ERROR);  
  19.             } else {//测试环境,alert异常信息 
  20.                  return new Result(1, StringUtils.isNotBlank(e.getMessage()) ? e.getMessage() : e.toString());  
  21.             }  
  22.         }  
  23.     }  

其中的AlertException为我们自定义的异常,因此当业务中需要抛出错误时,可以手动抛出AlertException。

以上就是统一处理返回值和统一处理异常的两步。

 

 

责任编辑:庞桂玉 来源: segmentfault
相关推荐

2023-12-05 14:10:00

接口可读性

2020-05-26 13:48:05

后端框架异常

2023-11-28 14:32:04

2017-05-18 14:14:25

过滤器Spring ClouZuul

2021-04-30 07:34:01

Spring BootController项目

2022-08-31 08:19:04

接口returnCode代码

2017-05-19 15:13:05

过滤器Spring ClouZuul

2017-07-31 15:47:50

Zuul统一处理

2023-11-30 07:00:56

SpringBoot处理器

2022-05-30 08:03:06

后端参数校验异常处理

2019-09-29 10:23:09

APIJava编程语言

2009-06-22 10:41:34

Spring.AOP

2022-05-07 10:09:01

开发Java日志

2020-11-10 10:21:31

架构try...catch代码

2010-06-13 10:19:16

统一计算私有云

2018-04-27 14:18:01

2021-10-11 19:34:03

全局格式项目

2011-06-20 06:14:00

ibmdwJava

2022-03-15 21:38:29

sentry微服务监控

2021-06-29 19:26:29

缓存Spring CachSpring
点赞
收藏

51CTO技术栈公众号