Introduction of depend on

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
Copy the code

The directory structure

1. Uniformly return interfaces

1.1 Unified response body definition

package com.suruomo.unified.result; import lombok.Getter; import lombok.Setter; /** * @author suruomo * @date 2020/8/7 15:36 * @description: Custom unified response body * VO (View Object) : Display layer Object, usually an Object transferred from the Web to the template rendering engine layer. */ @getter@setter public class ResultVO<T> {/** * status code, such as 1000, response success */ private int code; /** * private String MSG; /** * private T data; public ResultVO(T data) { this(ResultCode.SUCCESS, data); } public ResultVO(ResultCode resultCode, T data) { this.code = resultCode.getCode(); this.msg = resultCode.getMsg(); this.data = data; }}Copy the code

1.2 Enumerating status code definitions

package com.suruomo.unified.result; import lombok.Getter; /** * @author suruomo * @date 2020/8/7 16:10 * @description: Response code enumeration */ @getter Public enum ResultCode {//1000 series general error SUCCESS(1000, "operation succeeded "), FAILED(1001," interface error "), USER_NOT_EXIST(2000," user does not exist "), USER_NOT_EXIST(2000," user does not exist "), USER_LOGIN_FAIL(2001," wrong username or password "), USER_NOT_LOGIN(2002," user not logged in, please log in first "), NO_PERMISSION(2003," insufficient permission, please contact administrator "); private int code; private String msg; ResultCode(int code, String msg) { this.code = code; this.msg = msg; }}Copy the code

2. Entity class + parameter verification

package com.suruomo.unified.pojo; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import javax.validation.constraints.Email; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; /** * @author suruomo * @date 2020/8/7 15:41 * @description: @getter@setter@noargsconstructor Public class User {@notnull (message = "userid cannot be null ") private Long ID; @notnull (message = "user account cannot be empty ") @size (min = 6, Max = 11, message =" User account length must be 6-11 characters ") private String Account; @notnull (message = "user password cannot be empty ") @size (min = 6, Max = 11, message =" password must be 6-16 characters long ") private String password; @notnull (message = "user Email cannot be empty ") @email (message =" Email format is incorrect ") private String Email; }Copy the code

3. Handle global exceptions

3.1 Custom Exception APIException

package com.suruomo.unified.exception; import com.suruomo.unified.result.ResultCode; import lombok.Getter; /** * @author suruomo * @date 2020/8/7 16:43 * @description: Custom exception */ @getter Public class APIException extends RuntimeException {private int code; private String msg; public APIException() { this(ResultCode.FAILED); } public APIException(ResultCode failed) { this.code=failed.getCode(); this.msg=failed.getMsg(); }}Copy the code

2. Handle global exceptions in a unified manner

package com.suruomo.unified.exception; import com.suruomo.unified.result.ResultCode; import com.suruomo.unified.result.ResultVO; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.validation.ObjectError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; import java.util.ArrayList; import java.util.List; /** * @author suruomo * @date 2020/8/7 15:39 * @description: Slf4j Public Class GlobalExceptionHandler {/** * Custom exception APIException */ @ExceptionHandler(APIException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public ResultVO<Object> APIExceptionHandler(APIException e) {log.error(" API exception "); return new ResultVO<>(ResultCode.FAILED, e.getMsg()); } / method parameter error exception * * * * @ * @ return * / param e @ ExceptionHandler (MethodArgumentNotValidException. Class) @ResponseStatus(HttpStatus.BAD_REQUEST) public ResultVO<Object> MethodArgumentNotValidExceptionHandler (MethodArgumentNotValidException e) {log. The error (" abnormal method parameter error "); List<String> list=new ArrayList<>(); // Get ObjectError from the exception object if (! e.getBindingResult().getAllErrors().isEmpty()){ for(ObjectError error:e.getBindingResult().getAllErrors()){ list.add(error.getDefaultMessage().toString()); Return new ResultVO<>(resultcode.validate_failed, list); }}Copy the code

4. ResponseControllerAdvice – global deal with enhanced version of the Controller

  • Implement ResponseBodyAdvice interface
  • Override the supports and beforeBodyWrite methods
  • Avoid wrapping the returned data in the response body every time in the Controller
package com.suruomo.unified.controller; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.suruomo.unified.exception.APIException; import com.suruomo.unified.result.ResultVO; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; /** * @author suruomo * @date 2020/8/7 16:38 * @description: Global Processing Enhanced Controller, Avoid return data in the Controller response body is to be used for packaging every time * / @ RestControllerAdvice (basePackages = {" com. Suruomo. Unified. Controller "}) / / attention oh, Public class ResponseControllerAdvice implements ResponseBodyAdvice<Object> {@override public Boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<? >> aClass) {// If the interface returns a type that is itself ResultVO, there is no need to perform additional operations. Return false! returnType.getGenericParameterType().equals(ResultVO.class); } @Override public Object beforeBodyWrite(Object data, MethodParameter returnType, MediaType mediaType, Class<? extends HttpMessageConverter<? >> aClass, ServerHttpRequest, ServerHttpResponse ServerHttpResponse) {// String type cannot be wrapped directly, So for some special processing if (returnType. GetGenericParameterType (.) the equals (String. Class)) {ObjectMapper ObjectMapper = new ObjectMapper(); Try {/ / the data package in ResultVO, then converted to a json string response to the front return objectMapper. WriteValueAsString (new ResultVO < > (data)); } catch (JsonProcessingException e) { throw new APIException(); Return new ResultVO<>(data); return ResultVO<>(data); }}Copy the code

Note that the returned String data cannot be wrapped directly, so additional processing is required

5.TestController

package com.suruomo.unified.controller; import com.suruomo.unified.pojo.User; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; /** * @author suruomo * @date 2020/8/7 15:45 * @description: */ @RestController public class TestController { @GetMapping("/getUser") public User getUser() { User user = new User();  user.setId(1L); user.setAccount("12345678"); user.setPassword("12345678"); user.setEmail("[email protected]"); return user; } @PostMapping("/addUser") public void addUser(@Valid @RequestBody User user){ } }Copy the code

Test 6.

1. POST test

Test the request using Postman:Return result:

2. GET the test

Request:Return result: