boot 版本:2.4.4 本章节参考博客

  1. # 引入依赖
  2. # 该依赖中有一个 hibernate-validator 的包:org.hibernate:hibernate-validator
  3. implementation 'org.springframework.boot:spring-boot-starter-web'

构建需要校验的实体类

  1. public class Foo {
  2. @NotBlank
  3. private String name;
  4. @Min(18)
  5. private Integer age;
  6. @Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "手机号码格式错误")
  7. @NotBlank(message = "手机号码不能为空")
  8. private String phone;
  9. @Email(message = "邮箱格式错误")
  10. private String email;
  11. //... getter setter

框架提供的校验注解

  1. JSR提供的校验注解:
  2. @Null 被注释的元素必须为 null
  3. @NotNull 被注释的元素必须不为 null
  4. @AssertTrue 被注释的元素必须为 true
  5. @AssertFalse 被注释的元素必须为 false
  6. @Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  7. @Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  8. @DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  9. @DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  10. @Size(max=, min=) 被注释的元素的大小必须在指定的范围内
  11. @Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
  12. @Past 被注释的元素必须是一个过去的日期
  13. @Future 被注释的元素必须是一个将来的日期
  14. @Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
  15. Hibernate Validator提供的校验注解:
  16. @NotBlank(message =) 验证字符串非null,且长度必须大于0
  17. @Email 被注释的元素必须是电子邮箱地址
  18. @Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
  19. @NotEmpty 被注释的字符串的必须非空

在 @Controller 中校验

方式 1:在方法中自己获取到校验结果,自己处理后返回

  1. import org.springframework.validation.annotation.Validated;
  2. import org.springframework.validation.BindingResult;
  3. @Controller
  4. public class FooController {
  5. @RequestMapping("/foo")
  6. public String foo(@Validated Foo foo, BindingResult bindingResult) {
  7. // 判断是否有错误
  8. if(bindingResult.hasErrors()){
  9. // 获取到每个字段的错误信息
  10. for (FieldError fieldError : bindingResult.getFieldErrors()) {
  11. //...
  12. }
  13. return "fail";
  14. }
  15. return "success";
  16. }
  17. }

方式 2:利用全局处理器来实现

  1. import org.springframework.validation.BindException;
  2. import org.springframework.validation.BindingResult;
  3. import org.springframework.validation.FieldError;
  4. import org.springframework.web.bind.MethodArgumentNotValidException;
  5. import org.springframework.web.bind.annotation.ExceptionHandler;
  6. import org.springframework.web.bind.annotation.ResponseStatus;
  7. import org.springframework.web.bind.annotation.RestControllerAdvice;
  8. @Slf4j
  9. @RestControllerAdvice
  10. public class GlobalExceptionHandler {
  11. /**
  12. * 处理Validated校验异常
  13. * <p>
  14. * 注: 常见的 ConstraintViolationException 异常, 也属于 ValidationException 异常
  15. *
  16. * @param e 捕获到的异常
  17. * @return 返回给前端的 data
  18. */
  19. @ResponseStatus(code = HttpStatus.BAD_REQUEST)
  20. @ExceptionHandler(value = {BindException.class, ValidationException.class, MethodArgumentNotValidException.class})
  21. public Result handleParameterVerificationException(Exception e) {
  22. String msg = null;
  23. /// BindException
  24. if (e instanceof MethodArgumentNotValidException) {
  25. BindingResult bindingResult = ((MethodArgumentNotValidException) e).getBindingResult();
  26. // getFieldError 获取的是第一个不合法的参数(P.S.如果有多个参数不合法的话)
  27. FieldError fieldError = bindingResult.getFieldError();
  28. if (fieldError != null) {
  29. msg = fieldError.getField() + " " + fieldError.getDefaultMessage();
  30. }
  31. /// ValidationException 的子类异常 ConstraintViolationException
  32. } else if (e instanceof BindException) {
  33. // getFieldError 获取的是第一个不合法的参数(P.S.如果有多个参数不合法的话)
  34. FieldError fieldError = ((BindException) e).getFieldError();
  35. if (fieldError != null) {
  36. msg = fieldError.getField() + " " + fieldError.getDefaultMessage();
  37. }
  38. /// MethodArgumentNotValidException
  39. } else if (e instanceof ConstraintViolationException) {
  40. /*
  41. * ConstraintViolationException 的 e.getMessage() 形如
  42. * {方法名}.{参数名}: {message}
  43. * 这里只需要取后面的 message 即可
  44. */
  45. msg = e.getMessage();
  46. if (msg != null) {
  47. int lastIndex = msg.lastIndexOf(':');
  48. if (lastIndex >= 0) {
  49. msg = msg.substring(lastIndex + 1).trim();
  50. }
  51. }
  52. /// ValidationException 的其它子类异常
  53. } else {
  54. msg = "处理参数时异常: 参数校验未识别的异常类型";
  55. log.error(" 参数校验未识别的异常类型", e);
  56. }
  57. // 你自己封装的 result 类
  58. return ResultHelper.badRequest(msg);
  59. }
  60. }

手动调用方式校验

方式 1:使用 Hibernate Validation API

  1. Foo foo = new Foo();
  2. foo.setAge(22);
  3. foo.setEmail("000");
  4. // 通过这种方式获取到校验器
  5. ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
  6. Validator validator = vf.getValidator();
  7. Set<ConstraintViolation<Foo>> set = validator.validate(foo);
  8. for (ConstraintViolation<Foo> constraintViolation : set) {
  9. System.out.println(constraintViolation.getMessage());
  10. }

方式 2:使用 Spring 封装之后的校验器

  1. import javax.validation.ConstraintViolation;
  2. import javax.validation.Validator;
  3. // 直接注入这个校验器对象
  4. @Autowired
  5. private Validator globalValidator;
  6. final Set<ConstraintViolation<Foo>> errors = globalValidator.validate(foo);
  7. for (ConstraintViolation<Foo> constraintViolation : errors) {
  8. // 拿到错误的字段
  9. final String field = constraintViolation.getPropertyPath().toString();
  10. // 拿到错误的信息
  11. String error = constraintViolation.getMessage();
  12. }