【2022-05-19】接受才能发现
787 2023-04-03 04:24:56
前提:要先引入validation依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId></dependency>
Validation 2.x 的22个注解
一、实体类DTO校验
1、第一种Controller内部捕捉校验信息
①第一步定义dto,所有校验都在dto的属性上进行。
public class ValidatorDto { @NotEmpty(message = "名字不能为空!") public String name; @Email(message = "email格式不正确!") public String email; @Min(value = 10) public int age; @NotEmpty(message = "家庭住址至少填写一个") List<String> homList; public List<String> getHomList() { return homList; } public void setHomList(List<String> homList) { this.homList = homList; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }}
②第二步定义Controller,验证的参数dto属性要加@Validated,BindingResult参数中包含捕捉校验信息,程序执行过程会进入该方法体内。
@RestControllerpublic class TestValidatorController { @RequestMapping("/testValidator") @ResponseBody public ValidatorDto testValidator(@Validated ValidatorDto dto, BindingResult bindingResult) { if (bindingResult.hasErrors()) { List<ObjectError> listObjectError = bindingResult.getAllErrors(); for (ObjectError objectError : listObjectError) { System.out.println(objectError.getDefaultMessage()); } } return dto; }}
③访问参数及System.out.println输出的校验结果:
http://localhost:8080/testValidator?name=&email=@qq.com&age=5
最小不能小于10
家庭住址至少填写一个
名字不能为空!
email格式不正确!
2、第二种校验信息在抛出的异常中获取
①第一步定义dto,所有校验都在dto的属性上进行。
public class ValidatorDto { @NotEmpty(message = "名字不能为空!") public String name; @Email(message = "email格式不正确!") public String email; @Min(value = 10) public int age; public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }}
②第二步定义Controller,验证的参数dto属性要加@Validated,程序不会进入该方法体内,校验信息会在抛出的异常中被捕获(我使用的是全局异常@ControllerAdvice+@ExceptionHandler捕获异常信息)。
@RestControllerpublic class TestValidatorController { @RequestMapping("/testValidator2") @ResponseBody public ValidatorDto testValidator(@Validated ValidatorDto dto) { return dto; }}
③访问参数及校验结果:
http://localhost:8080/testValidator2?name=&email=@qq.com&age=5
3、分组校验
在不同情况下,可能对JavaBean对象的数据校验规则有所不同,有时需要根据数据状态对JavaBean中的某些属性字段进行单独验证,groups 属性将验证进行分组。
①第一步定义dto,所有校验都在dto的属性上进行。
分组一校验:name和age
分组二校验:email和age
public class ValidatorDto2 { @NotEmpty(message = "名字不能为空!", groups = ValidatorGroup1.class) public String name; @Email(message = "email格式不正确!", groups = ValidatorGroup2.class) public String email; @Min(value = 10, groups = { ValidatorGroup1.class, ValidatorGroup2.class }) public int age; public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }}
②第二步定义分组(2个空接口类),这两空接口类,就是上面dto中的groups 分组。
public interface ValidatorGroup1 {}
public interface ValidatorGroup2 {}
③第三步定义Controller,验证的参数dto属性要加@Validated,分组的class要放到Validated中,BindingResult参数中包含捕捉校验信息,程序执行过程会进入该方法体内。
RestControllerpublic class TestValidatorController { @RequestMapping("/testValidatorGroup1") @ResponseBody public ValidatorDto2 testValidatorGroup1(@Validated(ValidatorGroup1.class) ValidatorDto2 dto, BindingResult bindingResult) { if (bindingResult.hasErrors()) { List<ObjectError> listObjectError = bindingResult.getAllErrors(); for (ObjectError objectError : listObjectError) { System.out.println(objectError.getDefaultMessage()); } } return dto; } @RequestMapping("/testValidatorGroup2") @ResponseBody public ValidatorDto2 testValidatorGroup2(@Validated(ValidatorGroup2.class) ValidatorDto2 dto, BindingResult bindingResult) { if (bindingResult.hasErrors()) { List<ObjectError> listObjectError = bindingResult.getAllErrors(); for (ObjectError objectError : listObjectError) { System.out.println(objectError.getDefaultMessage()); } } return dto; }}
④访问参数及校验结果:
分组一:
http://localhost:8080/testValidatorGroup1?name=&email=@qq.com&age=5
名字不能为空!
最小不能小于10
分组二:
http://localhost:8080/testValidatorGroup2?name=&email=@qq.com&age=5
email格式不正确!
最小不能小于10
结果说明:name校验只属于分组一,email校验只属于分组二,age校验属于分组一和分组二,跟定义的dto定义一致。
二、直接参数校验
直接参数校验就是把dto中要校验的属性当做参数放到controller的参数内,所有的校验也都放到controller中参数中,其余处理和实体类DTO校验无差异。
三、自定义校验注解
预期:做一个判断非0的注解
①定义一个注解(仿照已有的现成注解做),其中@Constraint(validatedBy = NotEqualZeroValidator.class)的NotEqualZeroValidator为自己定义的校验类
@Documented@Constraint(validatedBy = NotEqualZeroValidator.class)@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE })@Retention(RetentionPolicy.RUNTIME)public @interface NotEqualZero String message() default "必须不等于0"; Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default { };}
②定义自己的校验类,需要实现ConstraintValidator<NotEqualZero, Object>接口
public class NotEqualZeroValidator implements ConstraintValidator<NotEqualZero, Object>{ @Override public boolean isValid(Object value, ConstraintValidatorContext context) { return (Integer)value != 0; }}
③使用自定义注解@NotEqualZero
public class ValidatorDto { @NotEmpty(message = "名字不能为空!") public String name; @Email(message = "email格式不正确!") public String email; @NotEqualZero public int age; @NotEmpty(message = "家庭住址至少填写一个") List<String> homeList; public List<String> getHomeList() { return homeList; } public void setHomeList(List<String> homeList) { this.homeList = homeList; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }}
④controller
@RestControllerpublic class TestValidatorController { @RequestMapping("/testValidator") @ResponseBody public ValidatorDto testValidator(@Validated ValidatorDto dto, BindingResult bindingResult) { if (bindingResult.hasErrors()) { List<ObjectError> listObjectError = bindingResult.getAllErrors(); for (ObjectError objectError : listObjectError) { System.out.println(objectError.getDefaultMessage()); } } return dto; }}
⑤结果
http://localhost:8080/testValidator?name=&email=@qq.com&age=0
名字不能为空!
email格式不正确!
家庭住址至少填写一个
必须不等于0