当前位置:   article > 正文

springboot是如何实现统一的返回格式_sprinboot定义统一返回格式

sprinboot定义统一返回格式

前言 

项目开发中,经常需要后端通常要给前端返回数据,后端程序员也经常会对数据进行自行封装,如果没有一个统一的规范,每个人都会自定义返回格式,这样一整,前端就会懵逼,骂娘,为了规避这种情况,就需要统一规范,统一给出相应数据格式,本文带你来看看springboot是如何实现的。

附录

参考的博客:SpringBoot 如何统一后端返回格式?老鸟们都是这样玩的! - 掘金

springboot常见返回格式

第一种,String

  1. @GetMapping(value = "/hello1")
  2. public String test5(){
  3. return "hello world";
  4. }
http://localhost:8080/hello1
hello world

第二种,json

  1. @GetMapping(value = "/hello2")
  2. public ValidVO test6(){
  3. ValidVO vo = new ValidVO();
  4. vo.setName("zhangsan");
  5. vo.setSex("男");
  6. return vo;
  7. }
http://localhost:8080/hello2
  1. {
  2. "id": null,
  3. "appId": null,
  4. "name": "zhangsan",
  5. "email": null,
  6. "sex": "男",
  7. "level": null
  8. }

第三种,异常形式

  1. @GetMapping(value = "/hello3")
  2. public void test7(){
  3. throw new RuntimeException("asdf");
  4. }
http://localhost:8080/hello3
  1. {
  2. "timestamp": "2021-12-08T09:11:51.371+00:00",
  3. "status": 500,
  4. "error": "Internal Server Error",
  5. "message": "",
  6. "path": "/hello3"
  7. }

如何统一返回格式

这里我们采用spring里面的@RestControllerAdvice+自定义注解的形式来实现。

具体思路如下。

第一步,定义统一响应实体类

这里我们就要思考,一个标准的响应都有哪些信息。

这里我们采用大多数公司采用的格式。

  1. code响应码:由后端统一定义各种返回结果的状态码
  2. msg描述:本次接口调用的结果描述
  3. data 数据:本次返回的数据
  1. {
  2. "code":"0",
  3. "msg":"成功",
  4. "data":[{
  5. "name":"张三",
  6. "age":"31"
  7. }]
  8. }

第二步,定义统一响应码

响应码的作用是让人快速知道返回的结果状态,见名知意。通常分为三大类,成功,失败,异常。

一些项目会有更专业的响应码,会对异常信息和相对应的错误码绑定,通过报出的错误码,查询错误码手册来获知项目的报错内容,从而定位问题,避免盲目。这样也使代码更优雅美观。

  1. @Data
  2. public class CommonResp<T> implements Serializable {
  3. private static final long serivalVersionUID = 1L;
  4. /**
  5. * 响应码
  6. */
  7. private String code = "0";
  8. /**
  9. * 响应信息
  10. */
  11. private String msg = "success";
  12. /**
  13. * 响应消息体
  14. */
  15. private T data;
  16. private CommonResp(){
  17. this.code = ResponseCodeEnum.SUCCESS.getCode();
  18. this.msg = ResponseCodeEnum.SUCCESS.getMsg();
  19. }
  20. private static CommonResp success(Object data){
  21. CommonResp result = new CommonResp();
  22. result.setData(data);
  23. return result;
  24. }
  25. }

第三步,把统一返回体封装成注解

springboot提供了一个接口ResponseBodyAdvice。

这个接口是起什么作用呢?

先看一波源码,如下

  1. /**
  2. *Allows customizing the response after the execution of an @ResponseBody or a
  3. *ResponseEntity controller method but before the body is written with an
  4. *HttpMessageConverter.
  5. *Implementations may be registered directly with RequestMappingHandlerAdapter and
  6. *ExceptionHandlerExceptionResolver or more likely annotated with @ControllerAdvice in
  7. *which case they will be auto-detected by both.
  8. *Since:
  9. *4.1
  10. *Author:
  11. *Rossen Stoyanchev
  12. *Type parameters:
  13. *<T> – the body type
  14. */
  15. public interface ResponseBodyAdvice<T> {
  16. /**
  17. * Whether this component supports the given controller method return type
  18. * and the selected {@code HttpMessageConverter} type.
  19. * @param returnType the return type
  20. * @param converterType the selected converter type
  21. * @return {@code true} if {@link #beforeBodyWrite} should be invoked;
  22. * {@code false} otherwise
  23. */
  24. boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType);
  25. /**
  26. * Invoked after an {@code HttpMessageConverter} is selected and just before
  27. * its write method is invoked.
  28. * @param body the body to be written
  29. * @param returnType the return type of the controller method
  30. * @param selectedContentType the content type selected through content negotiation
  31. * @param selectedConverterType the converter type selected to write to the response
  32. * @param request the current request
  33. * @param response the current response
  34. * @return the body that was passed in or a modified (possibly new) instance
  35. */
  36. @Nullable
  37. T beforeBodyWrite(@Nullable T body, MethodParameter returnType, MediaType selectedContentType,
  38. Class<? extends HttpMessageConverter<?>> selectedConverterType,
  39. ServerHttpRequest request, ServerHttpResponse response);
  40. }

来我给你翻译翻译:拦截Controller方法的返回值,统一处理返回值/响应体,一般用来统一返回格式,加解密,签名等等。

那么这个玩意怎么用呢?

我们只需实现这个接口,即可。

  1. @RestControllerAdvice
  2. public class CommonRespAdvice implements ResponseBodyAdvice<Object>{
  3. @Override
  4. public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
  5. boolean hasMethodAnnotation = returnType.hasMethodAnnotation(WrapCommonResp.class);
  6. if(!hasMethodAnnotation){
  7. WrapCommonResp wrapCommonResp = returnType.getMethod() == null ? null : returnType.getMethod().getDeclaringClass().getAnnotation(WrapCommonResp.class);
  8. if(wrapCommonResp != null){
  9. hasMethodAnnotation = true;
  10. }
  11. }
  12. return hasMethodAnnotation;
  13. }
  14. @Override
  15. public Object beforeBodyWrite(Object obj, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
  16. if(obj instanceof String){
  17. return JSON.toJSONString(CommonResp.success(obj));
  18. }
  19. return CommonResp.success(obj);
  20. }
  21. }

以上还涉及到一个注解:@RestControllerAdvice

这个注解是是 @RestController注解的增强,可以实现三个方面的功能:

  1. 全局异常处理
  2. 全局数据绑定
  3. 全局数据预处理
  1. if(obj instanceof String){
  2. return JSON.toJSONString(CommonResp.success(obj));
  3. }

注:这段代码一定要加,因为springboot对于string类型是直接返回的。

统一格式后的返回结果

  1. {
  2. "code": "0",
  3. "msg": "success",
  4. "data": {
  5. "id": null,
  6. "appId": null,
  7. "name": "zhangsan",
  8. "email": null,
  9. "sex": "男",
  10. "level": null
  11. }
  12. }

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号