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;
@Data
public 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注解
```java
package 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 {
//next
return null;
}
}
#Model#
package com.efly.gulimall.product.controller;
import lombok.Data;
import javax.validation.constraints.Min;
@Data
public 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);
}
#其他没有变化#
测试效果: