一,开发前工作
- 引入依赖
<dependency> <!--新版框架没有自动引入需要手动引入--> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
二,编写校验实例
(一)普通校验
1.实体类编写
@Data
public class User {
@NotNull(message = "用户id不能为空")
private Long id;
@NotNull(message = "用户账号不能为空")
@Size(min = 6, max = 11, message = "账号长度必须是6-11个字符")
private String account;
@NotNull(message = "用户密码不能为空")
@Size(min = 6, max = 11, message = "密码长度必须是6-16个字符")
private String password;
@NotNull(message = "用户邮箱不能为空")
@Email(message = "邮箱格式不正确")
private String email;
}
2.控制层代码
@RestController
@RequestMapping("user")
public class ValidationController {
@Autowired
private ValidationService validationService;
@PostMapping("/addUser")
public String addUser(@RequestBody @Validated User user) {
return validationService.addUser(user);
}
}
3.这样的话,就会把异常返回去,但是我们希望通过统一的前端实体类返回去,就要通过全局异常捕获实现
// 使用form data方式调用接口,校验异常抛出 BindException
// 使用 json 请求体调用接口,校验异常抛出 MethodArgumentNotValidException
// 单个参数校验异常抛出ConstraintViolationException
// 处理 json 请求体调用接口校验失败抛出的异常
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResultVO<String> MethodArgumentNotValidException(MethodArgumentNotValidException e) {
List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
List<String> collect = fieldErrors.stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.toList());
return new ResultVO(ResultCode.VALIDATE_FAILED, collect);
}
// 使用form data方式调用接口,校验异常抛出 BindException
@ExceptionHandler(BindException.class)
public ResultVO<String> BindException(BindException e) {
List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
List<String> collect = fieldErrors.stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.toList());
return new ResultVO(ResultCode.VALIDATE_FAILED, collect);
}
(二)分组检验
先说使用场景,我们有的时候同一个实体类会在多个接口反复使用,每个接口的入参校验规则不同,这个时候我们就要用到分组校验了
1.编写分组接口,用来区分不同的接口调用,里边无需编写任何代码
public interface Update extends Default{
}
@Data
public class User {
@NotNull(message = "用户id不能为空",groups = Update.class)
@NotNull(message = "用户id不空",groups = Update.class)
private Long id;
......
}
public interface Cat extends Default{
}
这里可以看到我们定义了两个接口,并且都继承了default接口,为什么要继承呢,因为如果我们对部分参数进行了参数校验并使用了分组,那没有分组的一些参数,在校验时就不会去校验了,只要我们继承了默认接口就可以实现,不管是否分组,都会进行校验
2.编写控制层
@PostMapping("update")
public String update(@Validated({Update.class}) User user) {
return "success";
}
这样的话,就实现了指定校验规则了
(三)嵌套校验
很好理解,假如不使用嵌套校验,那么假如校验的类中还有一个对象或者一个集合,那么就没办法实现校验了,实现方法也很简单,只需要在校验类的对象或者集合参数上,加上@Valid,在对象中编写具体的校验规则即可
1.实体类
@Data
public class User {
@NotNull(message = "用户id不能为空",groups = Update.class)
@NotNull(message = "用户id不空",groups = Update.class)
private Long id;
@Valid
private User user;
......
}
public class User{
@NotNull(message = "用户id不能为空",groups = Update.class)
private Long id;
}
这样假如传入的参数值User对象的id值为空,就会返回对应的参数校验结果