0


java使用Validation进行数据校验

在开发中,我们经常遇到参数校验的需求,比如用户注册的时候,要校验用户名不能为空、用户名长度不超过20个字符、手机号是合法的手机号格式等等。如果使用普通方式,我们会把校验的代码和真正的业务处理逻辑耦合在一起,而且如果未来要新增一种校验逻辑也需要在修改多个地方。而spring validation允许通过注解的方式来定义对象校验规则,把校验和业务逻辑分离开,让代码编写更加方便。Spring Validation其实就是对Hibernate Validator进一步的封装,方便在Spring中使用。

在Spring中有多种校验的方式

第一种是通过实现org.springframework.validation.Validator接口,然后在代码中调用这个类

第二种是按照Bean Validation方式来进行校验,即通过注解的方式。

第三种是基于方法实现校验

除此之外,还可以实现自定义校验


场景一:通过Validator接口实现

引入相关依赖

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.hibernate.validator</groupId>
  4. <artifactId>hibernate-validator</artifactId>
  5. <version>7.0.5.Final</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.glassfish</groupId>
  9. <artifactId>jakarta.el</artifactId>
  10. <version>4.0.1</version>
  11. </dependency>
  12. </dependencies>

创建实体类,定义属性和方法

  1. public class Person {
  2. private String name;
  3. private int age;
  4. public String getName() {
  5. return name;
  6. }
  7. public void setName(String name) {
  8. this.name = name;
  9. }
  10. public int getAge() {
  11. return age;
  12. }
  13. public void setAge(int age) {
  14. this.age = age;
  15. }
  16. }

创建类实现Validator接口,实现接口方法指定校验规则

  1. public class PersonValidator implements Validator {
  2. @Override
  3. public boolean supports(Class<?> clazz) {
  4. return Person.class.equals(clazz);
  5. }
  6. @Override
  7. public void validate(Object object, Errors errors) {
  8. ValidationUtils.rejectIfEmpty(errors, "name", "name.empty");
  9. Person p = (Person) object;
  10. if (p.getAge() < 0) {
  11. errors.rejectValue("age", "error value < 0");
  12. } else if (p.getAge() > 110) {
  13. errors.rejectValue("age", "error value too old");
  14. }
  15. }
  16. }

上面定义的类,其实就是实现接口中对应的方法,

supports方法用来表示此校验用在哪个类型上,

validate是设置校验逻辑的地点,其中ValidationUtils,是Spring封装的校验工具类,帮助快速实现校验。

使用上述Validator进行测试

  1. public static void main(String[] args) {
  2. //创建person对象
  3. Person person = new Person();
  4. person.setName("lucy");
  5. person.setAge(-1);
  6. // 创建Person对应的DataBinder
  7. DataBinder binder = new DataBinder(person);
  8. // 设置校验
  9. binder.setValidator(new PersonValidator());
  10. // 由于Person对象中的属性为空,所以校验不通过
  11. binder.validate();
  12. //输出结果
  13. BindingResult results = binder.getBindingResult();
  14. System.out.println(results.getAllErrors());
  15. }

场景二:Bean Validation注解实现

使用Bean Validation校验方式,就是如何将Bean Validation需要使用的javax.validation.ValidatorFactory 和javax.validation.Validator注入到容器中。spring默认有一个实现类LocalValidatorFactoryBean,它实现了上面Bean Validation中的接口,并且也实现了org.springframework.validation.Validator接口。

创建配置类,配置LocalValidatorFactoryBean

  1. @Configuration
  2. @ComponentScan("com.cj.spring6.validator.three")
  3. public class ValidationConfig {
  4. @Bean
  5. public MethodValidationPostProcessor validationPostProcessor() {
  6. return new MethodValidationPostProcessor();
  7. }
  8. }

创建实体类,使用注解定义校验规则

  1. public class User {
  2. @NotNull
  3. private String name;
  4. @Min(0)
  5. @Max(120)
  6. private int age;
  7. public String getName() {
  8. return name;
  9. }
  10. public void setName(String name) {
  11. this.name = name;
  12. }
  13. public int getAge() {
  14. return age;
  15. }
  16. public void setAge(int age) {
  17. this.age = age;
  18. }
  19. }

常用注解说明

@NotNull 限制必须不为null

@NotEmpty 只作用于字符串类型,字符串不为空,并且长度不为0

@NotBlank 只作用于字符串类型,字符串不为空,并且trim()后不为空串

@DecimalMax(value) 限制必须为一个不大于指定值的数字

@DecimalMin(value) 限制必须为一个不小于指定值的数字

@Max(value) 限制必须为一个不大于指定值的数字

@Min(value) 限制必须为一个不小于指定值的数字

@Pattern(value) 限制必须符合指定的正则表达式

@Size(max,min) 限制字符长度必须在min到max之间

@Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式

使用两种不同的校验器实现

使用jakarta.validation.Validator校验

  1. @Service
  2. public class MyService1 {
  3. @Autowired
  4. private Validator validator;
  5. public boolean validator(User user){
  6. Set<ConstraintViolation<User>> sets = validator.validate(user);
  7. return sets.isEmpty();
  8. }
  9. }

使用org.springframework.validation.Validator校验

  1. @Service
  2. public class MyService2 {
  3. @Autowired
  4. private Validator validator;
  5. public boolean validaPersonByValidator(User user) {
  6. BindException bindException = new BindException(user, user.getName());
  7. validator.validate(user, bindException);
  8. return bindException.hasErrors();
  9. }
  10. }

最后进行测试

  1. @Test
  2. public void testMyService1() {
  3. ApplicationContext context = new AnnotationConfigApplicationContext(ValidationConfig.class);
  4. MyService1 myService = context.getBean(MyService1.class);
  5. User user = new User();
  6. user.setAge(-1);
  7. boolean validator = myService.validator(user);
  8. System.out.println(validator);
  9. }
  10. @Test
  11. public void testMyService2() {
  12. ApplicationContext context = new AnnotationConfigApplicationContext(ValidationConfig.class);
  13. MyService2 myService = context.getBean(MyService2.class);
  14. User user = new User();
  15. user.setName("lucy");
  16. user.setAge(130);
  17. user.setAge(-1);
  18. boolean validator = myService.validaPersonByValidator(user);
  19. System.out.println(validator);
  20. }

场景三:基于方法实现校验

创建配置类,配置MethodValidationPostProcessor

  1. @Configuration
  2. @ComponentScan("com.cj.spring6.validator.two")
  3. public class ValidationConfig {
  4. @Bean
  5. public LocalValidatorFactoryBean validatorFactoryBean() {
  6. return new LocalValidatorFactoryBean();
  7. }
  8. }

创建实体类,使用注解设置校验规则

  1. import jakarta.validation.constraints.*;
  2. public class User {
  3. @NotNull
  4. private String name;
  5. @Min(0)
  6. @Max(120)
  7. private int age;
  8. @Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "手机号码格式错误")
  9. @NotBlank(message = "手机号码不能为空")
  10. private String phone;
  11. public String getName() {
  12. return name;
  13. }
  14. public void setName(String name) {
  15. this.name = name;
  16. }
  17. public int getAge() {
  18. return age;
  19. }
  20. public void setAge(int age) {
  21. this.age = age;
  22. }
  23. public String getPhone() {
  24. return phone;
  25. }
  26. public void setPhone(String phone) {
  27. this.phone = phone;
  28. }
  29. }

定义Service类,通过注解操作对象

  1. @Service
  2. @Validated
  3. public class MyService {
  4. public String testParams(@NotNull @Valid User user) {
  5. return user.toString();
  6. }
  7. }

最后测试

  1. @Test
  2. public void testMyService1() {
  3. ApplicationContext context = new AnnotationConfigApplicationContext(ValidationConfig.class);
  4. MyService myService = context.getBean(MyService.class);
  5. User user = new User();
  6. user.setAge(-1);
  7. myService.testParams(user);
  8. }
标签: java spring

本文转载自: https://blog.csdn.net/weixin_46759354/article/details/129917617
版权归原作者 你小子在看什么…… 所有, 如有侵权,请联系我们删除。

“java使用Validation进行数据校验”的评论:

还没有评论