1 基本概念

JSR-303 是 JAVA EE 6 中的一项子规范,叫做 Bean Validation,官方参考实现是Hibernate Validator。

2 基本校验规则

  1. 空值判断

@Null:验证对象是否为null
@NotNull:验证对象是否为null
@NotEmpty:验证对象是否为null+是否为Empty(如果字符串的长度为0,则为Emtpy)
@NotBlank:验证对象是否为null+Trim()掉字符串后是否还为Empty

3 使用步骤

3.1 导入依赖包

校验方式在“javax.validation.constraints”包,导入第三方包jar包到pom.xml文件

  1. # 注意:该包内部依赖了hibernate-validator组件
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-validation</artifactId>
  5. <version>2.5.3</version>
  6. </dependency>

3.2 在PoJo类上打上注解

3.2.1 带上注解(使用默认分组)

  1. package com.efly.gulimall.coupon.entity;
  2. import lombok.Data;
  3. import javax.validation.constraints.NotBlank;
  4. import javax.validation.constraints.NotEmpty;
  5. import javax.validation.constraints.NotNull;
  6. @Data
  7. public class CouponStudentModel {
  8. @NotNull(message = "年龄为必填")
  9. private Integer age;
  10. @NotEmpty(message="姓名不能为空")
  11. private String username;
  12. @NotBlank(message = "邮箱不能为空")
  13. private String email;
  14. }

3.2.2 带上注解(使用分组)

  1. 创建分组接口

    1. package com.efly.gulimall.coupon.valid;
    2. public interface AddGroup {
    3. }
  2. 为PoJo类属性指定分组 ```csharp package com.efly.gulimall.coupon.entity;

import com.efly.gulimall.coupon.valid.AddGroup; import com.efly.gulimall.coupon.valid.EditGroup; import lombok.Data;

import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import javax.validation.constraints.Null;

@Data public class CouponStudentModel { @Null(message = “新增的时候不能传值”, groups = AddGroup.class) @NotNull(message = “更新的时候必须传值”, groups = EditGroup.class) private Integer id;

  1. @NotEmpty(message = "姓名不能为空", groups = AddGroup.class)
  2. private String username;
  3. @NotBlank(message = "邮箱不能为空")
  4. private String email;

}

  1. ```csharp
  2. 注意:没有指定分组的PoJo将和没有指定分组的@Validated一一匹配,即没有指定分组的PoJo属性只在没有指定分组的@Validated上适用,反之亦然。如:
  3. PoJo类:
  4. @NotBlank(message = "邮箱不能为空")
  5. private String email;
  6. 方法:
  7. @RequestMapping("/add")
  8. public String add(@Validated CouponStudentModel model) {
  9. return "success";
  10. }
  1. 参数使用 ```csharp package com.efly.gulimall.coupon.controller;

import com.efly.gulimall.coupon.entity.CouponStudentModel; import com.efly.gulimall.coupon.valid.AddGroup; import com.efly.gulimall.coupon.valid.EditGroup; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;

@RestController @RequestMapping(“coupon/“)

public class CouponTestController {

  1. @RequestMapping("/add")
  2. public String add(@Validated(AddGroup.class) CouponStudentModel model) {
  3. return "success";
  4. }
  5. @RequestMapping("/edit")
  6. public String edit(@Validated(EditGroup.class) CouponStudentModel model) {
  7. return "success";
  8. }

}

  1. <a name="wi1OO"></a>
  2. ## 3.3 实际使用的地方带上@Validated注解
  3. ```java
  4. package com.efly.gulimall.coupon.controller;
  5. import com.efly.gulimall.coupon.entity.CouponStudentModel;
  6. import org.springframework.validation.annotation.Validated;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import org.springframework.web.bind.annotation.RestController;
  9. @RestController
  10. @RequestMapping("coupon/")
  11. public class CouponTestController {
  12. @RequestMapping("/test")
  13. public String Test(@Validated CouponStudentModel model) {
  14. return "success";
  15. }
  16. }

测试访问:如果前端访问时候不传入model对象,则控制台打印的错误日志信息
http://192.168.100.234:8000/coupon/test

  1. Field error in object 'couponStudentModel' on field 'age': rejected value [null]; codes [NotNull.couponStudentModel.age,NotNull.age,NotNull.java.lang.Integer,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [couponStudentModel.age,age]; arguments []; default message [age]]; default message [年龄为必填]
  2. Field error in object 'couponStudentModel' on field 'email': rejected value [null]; codes [NotBlank.couponStudentModel.email,NotBlank.email,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [couponStudentModel.email,email]; arguments []; default message [email]]; default message [邮箱不能为空]
  3. Field error in object 'couponStudentModel' on field 'username': rejected value [null]; codes [NotEmpty.couponStudentModel.username,NotEmpty.username,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [couponStudentModel.username,username]; arguments []; default message [username]]; default message [姓名不能为空]]

3.4 使用自定义异常类捕获异常

3.4.1 每个方法内部捕获异常

如果不使用自定义异常捕获机制,则需要在每个方法内部加判断

  1. #Controller#
  2. @RequestMapping("/check")
  3. public HashMap<String, String> check(@Valid StudentVO studentVO, BindingResult result) {
  4. if (result.hasErrors()) {
  5. HashMap<String, String> map = new HashMap<>();
  6. result.getFieldErrors().forEach((item) -> {
  7. //FieldError 获取到错误信息
  8. String message = item.getDefaultMessage();
  9. // 获取错误的属性的名字
  10. String field = item.getField();
  11. map.put(field, message);
  12. });
  13. return map;
  14. } else {
  15. //next
  16. return null;
  17. }
  18. }
  19. #Model#
  20. package com.efly.gulimall.product.controller;
  21. import lombok.Data;
  22. import javax.validation.constraints.Min;
  23. @Data
  24. public class StudentVO {
  25. @Min(5)
  26. private Integer userId;
  27. private String areaSchool;
  28. private Integer age;
  29. }

PostMan发送测试,提示#
image.png

3.4.2 全局捕获异常

详见全局异常处理一小节:https://www.yuque.com/zhuyufei-x9kmd/vwc1cy/qutkk1

  1. #控制器内部不再手动处理异常#
  2. @RequestMapping("/update65")
  3. public HashMap<String, String> update6(@Valid StudentVO studentVO) {
  4. return null;
  5. }
  6. #全局异常部分#
  7. @ExceptionHandler(value = {MethodArgumentNotValidException.class, BindException.class})
  8. public AjaxResult handleVaildException(BindException e) {
  9. log.error("数据校验出现问题{},异常类型:{}", e.getMessage(), e.getClass());
  10. BindingResult bindingResult = e.getBindingResult();
  11. Map<String, String> errorMap = new HashMap<>();
  12. bindingResult.getFieldErrors().forEach((fieldError) -> {
  13. errorMap.put(fieldError.getField(), fieldError.getDefaultMessage());
  14. });
  15. return AjaxResult.error("数据校验出现问题", errorMap);
  16. }
  17. #其他没有变化#

测试效果:
image.png