What I bring to you today is Spring Boot API Unified return format encapsulation , When we were working on the project API Interface returns need to be in a unified format , Only in this way can the front-end students handle the data returned by the interface in a unified way , It can also separate the front and rear ends
Pattern development , Just focus on the business , You don't have to deal with every returned result , The central idea is , All results are packaged as json, An error message is thrown through an exception , Return to the front end after unified capture processing , give an example : If you insert a user message , and
This user already exists in the system , Insert failure is returned , We use enumeration to define a return message , Throw by exception .
** explain : I have no official account , As long as this blog , It will also keep the blog updated , If it helps you , I hope you will keep your attention on **
Source code address https://gitee.com/zgc005/resut
Don't talk nonsense Code up
Let's start with the project structure
├── LICENSE
├── demo.iml
├── pom.xml
├── re
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── result
│ │ └── demo
│ │ ├── DemoApplication.java
│ │ ├── common
│ │ │ └── config
│ │ ├── global
│ │ │ ├── advice
│ │ │ │ ├── ExceptionResultAdvice.java ———— Exception capture . Handle .
│ │ │ │ └── ResponseResultAdvice.java ———— Interface returns unified encapsulation
│ │ │ ├── annotation
│ │ │ │ └── ResponseResult.java ———— Custom tag It is used to verify whether the interface needs to wrap return And verify that the interface exists
│ │ │ ├── config
│ │ │ │ └── GlobalConfig.java ———— Global configuration , Read *.yml Profile information
│ │ │ ├── enums
│ │ │ │ └── ResultCode.java ———— api Exception enumeration
│ │ │ ├── exception
│ │ │ │ └── BizException.java
│ │ │ ├── filterLists
│ │ │ │ ├── FilterConfig.java ———— Filter To configure
│ │ │ │ └── SignAuthFilter.java ———— Interface request signature verification and other operations
│ │ │ ├── interceptor
│ │ │ │ ├── ResponseResultInterceptor.java It is used to process whether the returned data needs encapsulation
│ │ │ │ └── WebConfigurer.java
│ │ │ ├── result
│ │ │ │ ├── EnumInterface.java
│ │ │ │ └── Result.java
│ │ │ └── sign
│ │ │ ├── BodyReaderHttpServletRequestWrapper.java ———— Processing of request flow
│ │ │ ├── HttpUtils.java
│ │ │ └── SignUtil.java
│ │ ├── modules
│ │ │ ├── goods
│ │ │ │ ├── controller
│ │ │ │ │ └── GoodsController.java
│ │ │ │ ├── dao
│ │ │ │ │ └── GoodsDao.java
│ │ │ │ ├── entity
│ │ │ │ │ ├── Goods.java
│ │ │ │ │ ├── GoodsBrandBean.java
│ │ │ │ │ ├── GoodsImage.java
│ │ │ │ │ ├── ProductEntity.java
│ │ │ │ │ └── TestName.java
│ │ │ │ └── service
│ │ │ │ ├── GoodsService.java
│ │ │ │ └── impl
│ │ │ │ └── GoodsServiceImpl.java
│ │ │ ├── order
│ │ │ │ ├── controller
│ │ │ │ ├── dao
│ │ │ │ ├── entity
│ │ │ │ └── service
│ │ │ ├── user
│ │ │ │ ├── controller
│ │ │ │ ├── dao
│ │ │ │ ├── entity
│ │ │ │ └── service
│ │ │ └── util
│ │ │ └── JsonTOpagaData.java
│ │ ├── scheduled
│ │ │ ├── ScheduledMachine.java
│ │ │ └── ScheduledProduct.java
│ │ └── test
│ │ ├── Demo.java
│ │ └── Test.java
│ └── resources
│ ├── application-dev.yml
│ ├── application-pro.yml
│ ├── application-test.yml
│ ├── application.yml
│ └── mapper
│ ├── goods
│ │ └── GoodsDao.xml
│ ├── machine
│ │ └── MachineDao.xml
│ ├── order
│ └── user
└── test
└── java
└── com
└── result
└── demo
└── DemoApplicationTests.java
Here are a few core classes
- ExceptionResultAdvice : All exceptions will be caught by this class , Handle , If there's something new Exception Just add a new method , If a new one is added XXXException Methods
@ExceptionHandler(value = XXXException.class)
public Result XXXexceptionHandler(XXXException xxxexception){
log.info(" System exception handling :{}",xxxexception);
return Result.error();
}
- ResponseResultAdvice: Rewrite the returned data , This class is mainly used to encapsulate the returned results , And it doesn't have to be in every Controller The method in the , Simplify the code , Focus only on the business .
There's a pit here :ResponseBodyAdvice If the return type is String I'll make a mistake , You can check the reason by yourself , So this place has to be about String Type of data
@Override
public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
log.info(" Enter return to propose rewriting format In processing ......");
Result result = new Result();
// contain Result The explanation is abnormal
if (body instanceof Result) {
return body;
}
if (body instanceof String) {
String str = JSON.toJSONString(Result.success(body));
return str;
}
return Result.success(body);
}
- ResponseResult: This is a custom tag , It's mainly used to judge Controller Whether the returned data of the class needs to be encapsulated. The usage is as follows
@Slf4j
@RestController
@RequestMapping(value = "/api")
@ResponseResult
public class Test {
}
stay ResponseResultInterceptor Class will judge and process this tag .
public class ResponseResultInterceptor implements HandlerInterceptor {
public static final String RESPONSE_RESULT_ANN = "RESPONSE-RESULT-ANN";
/**
* The core idea of this code , To get this request , Whether return value packing is needed , Set a property tag .
*
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// Method validation
if (handler instanceof HandlerMethod) {
final HandlerMethod handlerMethod = (HandlerMethod) handler;
final Class<?> clazz = handlerMethod.getBeanType();
final Method method = handlerMethod.getMethod();
if (clazz.isAnnotationPresent(ResponseResult.class)) {
request.setAttribute(RESPONSE_RESULT_ANN, clazz.getAnnotation(ResponseResult.class));
} else if (method.isAnnotationPresent(ResponseResult.class)) {
request.setAttribute(RESPONSE_RESULT_ANN, method.getAnnotation(ResponseResult.class));
}
return true;
} else {
return initResponse(response, ResultCode.API_NOT_EXIST);
}
}
private boolean initResponse(HttpServletResponse response,ResultCode resultCode) throws IOException {
response.setCharacterEncoding("utf-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter writer = response.getWriter();
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", resultCode.getCode());
jsonObject.put("message", resultCode.getMessage());
jsonObject.put("data", null);
writer.write(jsonObject.toString());
return false;
}