1 基本概念
JSR-303 是 JAVA EE 6 中的一项子规范,叫做 Bean Validation,官方参考实现是Hibernate Validator。
2 基本校验规则
- 空值判断
@Null:验证对象是否为null
@NotNull:验证对象是否为null
@NotEmpty:验证对象是否为null+是否为Empty(如果字符串的长度为0,则为Emtpy)
@NotBlank:验证对象是否为null+Trim()掉字符串后是否还为Empty
3 使用步骤
3.1 导入依赖包
校验方式在“javax.validation.constraints”包,导入第三方包jar包到pom.xml文件
# 注意:该包内部依赖了hibernate-validator组件<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId><version>2.5.3</version></dependency>
3.2 在PoJo类上打上注解
3.2.1 带上注解(使用默认分组)
package com.efly.gulimall.coupon.entity;import lombok.Data;import javax.validation.constraints.NotBlank;import javax.validation.constraints.NotEmpty;import javax.validation.constraints.NotNull;@Datapublic class CouponStudentModel {@NotNull(message = "年龄为必填")private Integer age;@NotEmpty(message="姓名不能为空")private String username;@NotBlank(message = "邮箱不能为空")private String email;}
3.2.2 带上注解(使用分组)
创建分组接口
package com.efly.gulimall.coupon.valid;public interface AddGroup {}
为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;
@NotEmpty(message = "姓名不能为空", groups = AddGroup.class)private String username;@NotBlank(message = "邮箱不能为空")private String email;
}
```csharp注意:没有指定分组的PoJo将和没有指定分组的@Validated一一匹配,即没有指定分组的PoJo属性只在没有指定分组的@Validated上适用,反之亦然。如:PoJo类:@NotBlank(message = "邮箱不能为空")private String email;方法:@RequestMapping("/add")public String add(@Validated CouponStudentModel model) {return "success";}
- 参数使用 ```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 {
@RequestMapping("/add")public String add(@Validated(AddGroup.class) CouponStudentModel model) {return "success";}@RequestMapping("/edit")public String edit(@Validated(EditGroup.class) CouponStudentModel model) {return "success";}
}
<a name="wi1OO"></a>## 3.3 实际使用的地方带上@Validated注解```javapackage com.efly.gulimall.coupon.controller;import com.efly.gulimall.coupon.entity.CouponStudentModel;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 {@RequestMapping("/test")public String Test(@Validated CouponStudentModel model) {return "success";}}
测试访问:如果前端访问时候不传入model对象,则控制台打印的错误日志信息
http://192.168.100.234:8000/coupon/test
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 [年龄为必填]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 [邮箱不能为空]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 每个方法内部捕获异常
如果不使用自定义异常捕获机制,则需要在每个方法内部加判断
#Controller#@RequestMapping("/check")public HashMap<String, String> check(@Valid StudentVO studentVO, BindingResult result) {if (result.hasErrors()) {HashMap<String, String> map = new HashMap<>();result.getFieldErrors().forEach((item) -> {//FieldError 获取到错误信息String message = item.getDefaultMessage();// 获取错误的属性的名字String field = item.getField();map.put(field, message);});return map;} else {//nextreturn null;}}#Model#package com.efly.gulimall.product.controller;import lombok.Data;import javax.validation.constraints.Min;@Datapublic class StudentVO {@Min(5)private Integer userId;private String areaSchool;private Integer age;}
PostMan发送测试,提示#

3.4.2 全局捕获异常
详见全局异常处理一小节:https://www.yuque.com/zhuyufei-x9kmd/vwc1cy/qutkk1
#控制器内部不再手动处理异常#@RequestMapping("/update65")public HashMap<String, String> update6(@Valid StudentVO studentVO) {return null;}#全局异常部分#@ExceptionHandler(value = {MethodArgumentNotValidException.class, BindException.class})public AjaxResult handleVaildException(BindException e) {log.error("数据校验出现问题{},异常类型:{}", e.getMessage(), e.getClass());BindingResult bindingResult = e.getBindingResult();Map<String, String> errorMap = new HashMap<>();bindingResult.getFieldErrors().forEach((fieldError) -> {errorMap.put(fieldError.getField(), fieldError.getDefaultMessage());});return AjaxResult.error("数据校验出现问题", errorMap);}#其他没有变化#
测试效果:
