1. 依赖版本
(1)SpringBoot 3.1.11
(2)JDK17
2. @Valid、@Validated 简介
说明:在Spring框架中@Valid默认不会对集合(List、Set等)内部的元素进行校验,需要将Spring提供的@Validated注解放在controller类上搭配使用。
2.1 @Valid
- 提供者:validation-api;
- 使用位置:成员属性、构造函数、方法、方法参数;
- 分组:不支持;
- 嵌套校验:支持嵌套校验,@Valid可以使用在成员属性上。
2.2 @Validated
- 提供者:Spring自定义注解;
- 使用位置:类、方法、方法参数,不能用于成员属性;
- 分组:支持分组,参数校验时,根据不同的分组进行不同的校验;
- 嵌套校验:不支持。
3. 示例
(1)引入依赖
<!-- 数据校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
(2)实体类
- Student
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import java.util.List;
@Data
public class Student {
@NotBlank(message = "编号不能为空")
private String id;
@NotBlank(message = "名字不能为空")
@Length(max = 10,message = "长度不能超过20")
private String name;
@NotBlank(message = "编号不能为空")
private String sex;
@NotBlank(message = "编号不能为空")
private String age;
@Valid
private Address addr;
@Valid
private List<Hobby> hobbies;
}
- Address
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class Address {
@NotBlank(message = "地址编号不能为空")
private String addrId;
@NotBlank(message = "城市不能为空")
private String city;
}
- Hobby
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class Hobby {
@NotBlank(message = "爱好编号不能为空")
private String hobbyId;
@NotBlank(message = "爱好编号不能为空")
private String hobby;
}
(3)数据校验异常处理
import com.wen.vo.ResultVo;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@RestControllerAdvice
public class ExceptionCatch {
/**
* 数据校验异常处理
* @param e
* @return
*/
@ExceptionHandler(value= MethodArgumentNotValidException.class)
public ResultVo validateException(MethodArgumentNotValidException e){
BindingResult bindingResult=e.getBindingResult();
Map<String,Object> map=new HashMap<>();
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
map.put(fieldError.getField(),fieldError.getDefaultMessage());
}
return ResultVo.fail("数据校验异常",map);
}
@ExceptionHandler(value= ConstraintViolationException.class)
public ResultVo validateException(ConstraintViolationException e){
Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
Map<String,Object> map=new HashMap<>();
for (ConstraintViolation<?> constraintViolation : constraintViolations) {
map.put(constraintViolation.getPropertyPath().toString(),constraintViolation.getMessage());
}
return ResultVo.fail("数据校验异常",map);
}
}
3.1 @Valid嵌套校验
3.1.1 controller层
@RestController
@RequestMapping("/stu")
public class StudentController {
@PostMapping
public String addStu(@Valid @RequestBody Student student){
System.out.println(student);
return "新增成功";
}
}
3.1.2 测试
(1)全量数据
(2)异常数据
3.2 @Valid校验集合
3.2.1 controller层
注意:使用@Valid校验集合内部元素需要将Spring提供的@Validated注解放在controller类上搭配使用。
@Validated // 校验入参是集合的数据需要
@RestController
@RequestMapping("/stu")
public class StuController {
@PostMapping("/batchAdd")
public String batchAddStu(@Valid @RequestBody List<Student> students){
System.out.println(students);
return "批量新增成功";
}
}
3.2.2 测试
(1)全量数据
(2)异常数据