1. 依赖引入

版本号跟随使用的 spring boot 版本即可,本例中使用的版本号为:3.2.3

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

2. 校验注解使用样例

2.1

参数对象的两个 String 类型的属性添加非空校验注解:@NotBlank,可以校验 null 值以及空字符串。

@Value
@Builder
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class PasswordLoginCommand implements Command {

    @NotBlank 
    String username;

    @NotBlank
    String password;

}

校验框架默认提供很多常用的注解,具体罗列如下:

validation

引用自:https://segmentfault.com/a/1190000023451809

2.2

需要校验的参数对象前必须添加 @Valid 注解,否校验不会生效。

@RestController
public class LoginController {

    LoginCommandService loginCommandService;

    @PostMapping("/login")
    public void loginWithPassword(HttpServletRequest request,
                                  HttpServletResponse response,
                                  @RequestBody @Valid PasswordLoginCommand command) {
        String token = loginCommandService.loginWithPassword(command);
        response.addCookie(new Cookie(Constants.AUTH_COOKIE_NAME, token));
    }

}

3. 校验异常处理

校验失败会抛出 MethodArgumentNotValidException 类型的异常,可以在 Controller 层的全局异常处理中捕获进行处理,之后按照统一的响应格式返回响应消息。

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ResponseStatus
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleValidationException(MethodArgumentNotValidException ex) {
        List<ObjectError> objectErrors = ex.getBindingResult().getAllErrors();
        Map<String, String> errors = new HashMap<>(objectErrors.size());
        objectErrors.forEach(error -> {
            String fieldName = ((FieldError) error).getField();
            String errorMessage = error.getDefaultMessage();
            errors.put(fieldName, errorMessage);
        });
        return Result.error(ResultCodeEnum.SERVER_ERROR, errors.toString());
    }

}