中国建设招标网是什么网站,龙之网官网,代做一个网站多少钱,自己有域名要怎么制作网站个人简介#xff1a;Java领域新星创作者#xff1b;阿里云技术博主、星级博主、专家博主#xff1b;正在Java学习的路上摸爬滚打#xff0c;记录学习的过程~ 个人主页#xff1a;.29.的博客 学习社区#xff1a;进去逛一逛~ Spring Validation 数据校验一、什么是 Spring… 个人简介Java领域新星创作者阿里云技术博主、星级博主、专家博主正在Java学习的路上摸爬滚打记录学习的过程~ 个人主页.29.的博客 学习社区进去逛一逛~ Spring Validation 数据校验一、什么是 Spring Validation二、实现数据校验准备相关jar包⚪Validator接口方式⚪基于注解方式Bean Validation⚪基于方法的方式⚪自定义校验一、什么是 Spring Validation 在开发中我们经常遇到参数校验的需求比如用户注册的时候要校验用户名不能为空、用户名长度不超过20个字符、手机号是合法的手机号格式等等。 如果使用普通方式我们会把校验的代码和真正的业务处理逻辑耦合在一起而且如果未来要新增一种校验逻辑也需要在修改多个地方。 而spring validation允许通过注解的方式来定义对象校验规则把校验和业务逻辑分离开让代码编写更加方便。 Spring Validation其实就是对Hibernate Validator进一步的封装方便在Spring中使用。 Spring提供了数种数据校验的方式
实现org.springframework.validation.Validator接口调用接口实现类通过 注解 方式进行数据校验按照Bean Validation方式基于 方法(函数) 实现数据校验自定义校验 二、实现数据校验 准备相关jar包
引入Maven依赖 dependencies!-- validator校验相关依赖 --dependencygroupIdorg.hibernate.validator/groupIdartifactIdhibernate-validator/artifactIdversion7.0.5.Final/version/dependencydependencygroupIdorg.glassfish/groupIdartifactIdjakarta.el/artifactIdversion4.0.1/version/dependency/dependencies
注意上述依赖还不够请记得添加spring的基础依赖和Junit测试等依赖⚪Validator接口方式 这是一个用于测试校验的实体类
/*** author .29.* create 2023-03-01 10:58*///创建实体类定义属性及方法供校验测试
public class Person {private String name;private int age;public int getAge() {return age;}public void setAge(int age) {this.age age;}public String getName() {return name;}public void setName(String name) {this.name name;}}这是一个实现了Validator接口的实体类
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;/*** author .29.* create 2023-03-01 11:00*/
//validator接口方式实现 校验
public class PersonValidator implements Validator {Overridepublic boolean supports(Class? aClass) {return Person.class.equals(aClass); //比对实体类的类对象与参数是否一致}Overridepublic void validate(Object o, Errors errors) { //重写校验方法//设置name为空时报错name.emptyValidationUtils.rejectIfEmpty(errors,name,name.empty);//传入对象强转为实体类Person对象Person p (Person)o;if(p.getAge() 0){ //设置age属性小于零时报错errors.rejectValue(age,error (age 0));}else if(p.getAge() 110){//设置age属性大于110报错errors.rejectValue(age,error (age 110) too old !!);}}
} 校验测试
import org.springframework.validation.BindingResult;
import org.springframework.validation.DataBinder;/*** author .29.* create 2023-03-01 11:21*/
public class testPersonValidator {public static void main(String[] args){Person person new Person();
// person.setName(高启强);
// person.setAge(29);//创建person对象的DataBinderDataBinder binder new DataBinder(person);//设置校验binder.setValidator(new PersonValidator());//校验(当person属性值为空时校验不通过)binder.validate();//输出校验结果//binder.getBindingResult() 获取校验结果对象//bindingResult.getAllErrors() 获取所有校验到的错误BindingResult bindingResult binder.getBindingResult();System.out.println(bindingResult.getAllErrors());}
}没有传入参数时对象为空得到 name.empty 的校验错误 [Field error in object ‘target’ on field ‘name’: rejected value [null]; codes [name.empty.target.name,name.empty.name,name.empty.java.lang.String,name.empty]; arguments []; default message [null]]
传入正确参数后没有校验错误可输出 [] ⚪基于注解方式Bean Validation
使用Bean Validation校验方式就是如何将Bean Validation需要使用的javax.validation.ValidatorFactory 和javax.validation.Validator注入到容器中。spring默认有一个实现类LocalValidatorFactoryBean它实现了上面Bean Validation中的接口并且也实现了org.springframework.validation.Validator接口。 这是一个配置了配置LocalValidatorFactoryBean的配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;/*** author .29.* create 2023-03-01 11:34*/
//配置类
Configuration //声明为Spring配置类
ComponentScan(com.haojin.spring.config) //设置需要扫描的包
public class ValidationConfig {Bean //返回值放入ioc容器public LocalValidatorFactoryBean validator() {return new LocalValidatorFactoryBean();}
}这是一个用于测试校验的实体类
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;/*** author .29.* create 2023-03-01 11:36*/
//实体类使用注解定义校验规则
public class User {NotNull //不可为空private String name;Min(0) //最小值Max(110) //最大值private int age;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;}
}这里总结一下常见的注解
NotNull 限制必须不为nullNotEmpty 只作用于字符串类型字符串不为空并且长度不为0NotBlank 只作用于字符串类型字符串不为空并且trim()后不为空串DecimalMax(value) 限制必须为一个不大于指定值的数字DecimalMin(value) 限制必须为一个不小于指定值的数字Max(value) 限制必须为一个不大于指定值的数字Min(value) 限制必须为一个不小于指定值的数字Pattern(value) 限制必须符合指定的正则表达式Size(max,min) 限制字符长度必须在min到max之间Email 验证注解的元素值是Email也可以通过正则表达式和flag指定自定义的email格式 接下来设置校验器两种方式
方式一使用java原生的jakarta.validation.Validator校验
校验器一号
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Set;/*** author .29.* create 2023-03-01 11:39*/
//使用java原生的jakarta.validation.Validator校验
Service
public class MyService1 {Autowired //自动装配Validator对象private Validator validator;//校验方法public boolean validator(User user){//校验后的结果存放进Set集合SetConstraintViolationUser set validator.validate(user);//若没有校验到错误集合为空返回true。return set.isEmpty();}
}方式二用spring提供的validator校验
校验器一号
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindException;
import org.springframework.validation.Validator;/*** author .29.* create 2023-03-02 9:24*/
//使用spring提供的validate校验方法
Service
public class MyService2 {Autowiredprivate Validator validator;public boolean validator2(User user){BindException bindException new BindException(user,user.getName());validator.validate(user,bindException); //调用校验方法进行校验System.out.println(bindException.getAllErrors()); //输出所有错误信息return bindException.hasErrors(); //若没有异常返回false}}创建测试类分别测试两种校验器
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;/*** author .29.* create 2023-03-02 9:33*/
public class testBeanValidator {Testpublic void testValidatorOne(){//获取context对象AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(ValidationConfig.class);//校验器的实现类对象MyService1 myValidatorOne context.getBean(MyService1.class);User user new User();boolean validator myValidatorOne.validator(user);System.out.println(validator);}Testpublic void testValidatorTwo(){//获取context对象AnnotationConfigApplicationContext annotationConfigApplicationContext new AnnotationConfigApplicationContext(ValidationConfig.class);//校验器的实现类对象MyService2 myValidatorTwo annotationConfigApplicationContext.getBean(MyService2.class);User user new User();boolean validator myValidatorTwo.validator2(user);System.out.println(validator);}
}⚪基于方法的方式
这是一个配置了MethodValidationPostProcessor的配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;/*** author .29.* create 2023-03-02 18:28*/
//配置了MethodValidationPostProcessor的配置类
Configuration
ComponentScan(com.haojin.spring.three)
public class validationPostProcessor {Beanpublic MethodValidationPostProcessor methodValidationPostProcessor(){return new MethodValidationPostProcessor();}
} 这是一个测试校验的实体类校验规则通过注解设置
import jakarta.validation.constraints.*;/*** author .29.* create 2023-03-02 18:30*/
public class User {NotNullprivate String name;Min(0)Max(129)private int age;//手机号格式 1开头 第二位是3、4、6、7、9其一后面是9位数字Pattern(regexp ^1(3|4|6|7|9)\\d{9}$,message 手机号码格式错误)NotBlank(message 手机号码不能为空)private String phone;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;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone phone;}Overridepublic String toString() {return User{ name name \ , age age , phone phone \ };}
} 定义Service类通过注解操作对象
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;/*** author .29.* create 2023-03-02 18:35*/
Service
Validated
public class MyService { //定义Service类通过注解操作对象public String testParams(NotNull Valid User user){return user.toString();}
} 测试
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;/*** author .29.* create 2023-03-02 18:37*/
public class TestMethod {Testpublic void testMyService(){AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(validationPostProcessor.class);MyService bean context.getBean(MyService.class);User user new User();bean.testParams(user);}
} ⚪自定义校验
自定义设置校验规则的注解
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.*;Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
Retention(RetentionPolicy.RUNTIME)
Documented
Constraint(validatedBy {CannotBlankValidator.class})
public interface CannotBlank {//默认错误消息String message() default 不能包含空格;//分组Class?[] groups() default {};//负载Class? extends Payload[] payload() default {};//指定多个时使用Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})Retention(RetentionPolicy.RUNTIME)Documentedinterface List {CannotBlank[] value();}
}编写校验类
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;public class CannotBlankValidator implements ConstraintValidatorCannotBlank, String {Overridepublic void initialize(CannotBlank constraintAnnotation) {}Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {//null时不进行校验if (value ! null value.contains( )) {//获取默认提示信息String defaultConstraintMessageTemplate context.getDefaultConstraintMessageTemplate();System.out.println(default message : defaultConstraintMessageTemplate);//禁用默认提示信息context.disableDefaultConstraintViolation();//设置提示语context.buildConstraintViolationWithTemplate(can not contains blank).addConstraintViolation();return false;}return true;}
}