当前位置:网站首页>Bean validation beginner ----02
Bean validation beginner ----02
2022-07-23 16:12:00 【Big flicker love flicker】
Bean Validation Introduction ----02
Last one It introduces JSR、Bean Validation、Hibernate Validator Connection and difference of , The beginning of this article , To explore how to use good Bean Validation modular , To complete the tedious data verification function .
Declarative validation method parameters 、 Return value
A lot of times , We are just some simple independent parameters ( For example, the method input parameter int age), There is no need to make a big fight Java Bean Pack up , For example, I hope to write like this to achieve the corresponding constraint effect :
public @NotNull Person getOne(@NotNull @Min(1) Integer id, String name) {
... };
Now let's discuss how to use Bean Validation elegant 、 Declarative implementation method parameters 、 Return value and constructor parameters 、 Verification of return value .
Declarative except for code elegance 、 In addition to the benefits of no invasion , Another advantage that cannot be ignored is : Anyone only needs to look at the declaration to know the semantics , You don't need to know your implementation , It's also more secure to use .
Bean Validation 1.0 Version only supports Java Bean check , To 1.1 The version already supports the method / Verification of construction method , The calibrator used is 1.1 New version of ExecutableValidator:
public interface ExecutableValidator {
// Method validation : Parameters + Return value
<T> Set<ConstraintViolation<T>> validateParameters(T object,
Method method,
Object[] parameterValues,
Class<?>... groups);
<T> Set<ConstraintViolation<T>> validateReturnValue(T object,
Method method,
Object returnValue,
Class<?>... groups);
// Constructor validation : Parameters + Return value
<T> Set<ConstraintViolation<T>> validateConstructorParameters(Constructor<? extends T> constructor,
Object[] parameterValues,
Class<?>... groups);
<T> Set<ConstraintViolation<T>> validateConstructorReturnValue(Constructor<? extends T> constructor,
T createdObject,
Class<?>... groups);
}
In fact, we are right Executable The word is no stranger , towards JDK The interface of java.lang.reflect.Executable Its only two implementations are Method and Constructor, It just echoes here .
Before the following code example , First, two methods are provided to obtain the verifier ( Use default configuration ), Convenient for subsequent use :
public class ValidatorUtil {
/** * be used for Java Bean Verifier for verification */
public static Validator obtainValidator() {
// 1、 Use 【 The default configuration 】 Get a calibration factory This configuration can come from provider、SPI Provide
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
// 2、 Get a calibrator
return validatorFactory.getValidator();
}
/** * Verifier for method verification */
public static ExecutableValidator obtainExecutableValidator() {
return obtainValidator().forExecutables();
}
}
because Validator Wait for the verifier to be thread safe , Therefore, generally speaking, an application only needs one copy , So it only needs to be initialized once .
check Java Bean
Let's review it first Java Bean The verification method of . Writing JavaBean And the verification program ( All use JSR standard API), Constraint annotations on declarations :
@Test
public void testBeanValidator(){
Stu stu = new Stu();
stu.setNum(-1);
Set<ConstraintViolation<Stu>> result = ValidatorUtil.obtainValidator().validate(stu);
result.stream().map(v -> v.getPropertyPath() + " " + v.getMessage() + ": "
+ v.getInvalidValue()).forEach(System.out::println);
}
Output results :
name Not for null: null
num The minimum cannot be less than 0: -1
This is the most classic application . So here comes the question , If your method parameter is a Java Bean, How do you verify it ?
Tips: : Some people think that the constraint annotation is marked on the attribute , And marked in set The effect of the method is the same , It's not , You have this illusion because Spring Helped you deal with something , As for the reason, it will be later and Spring Expand when integrating
Verification method
Let's try it now , Use the ExecutableValidator Complete the verification of method parameters :
public Boolean updateStu(@Min(value = 0) Integer num, @NotEmpty String name){
System.out.println(num);
System.out.println(name);
return true;
}
@Test
public void testBeanValidator() throws NoSuchMethodException {
Method updateStu = this.getClass().getMethod("updateStu", Integer.class, String.class);
Set<ConstraintViolation<TestDataBinder>> validResult = ValidatorUtil.obtainExecutableValidator().validateParameters(this, updateStu, new Object[]{
-1, ""});
if (!validResult.isEmpty()) {
// ... Output error details validResult
validResult.stream().map(v -> v.getPropertyPath() + " " + v.getMessage() + ": " + v.getInvalidValue()).forEach(System.out::println);
throw new IllegalArgumentException(" Parameter error ");
}
}

Perfectly in line with expectations . however ,arg0 What the hell is it ?
- Java class The bytecode file does not record the real method parameter name by default , But by default arg0,arg1 Instead of
- stay JDK 8 after , We can specify “-parameters” Options , To write the parameter name of the method to class file , And obtain the corresponding parameter name through the reflection mechanism at runtime .
Maven The project can be carried out in pom It is specified in
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>utf8</encoding>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
For the verification of the construction method and the verification of the method return value , It's the same thing , Not much here
Java Bean How to verify as an input parameter ?
If one Java Bean When method parameters , How should you use Bean Validation Check ?
public Boolean updateStu(Stu stu){
return false;
}
@Data
public class Stu {
@Min(value = 0)
Integer num;
@NotNull
String name;
}
To test :
@Test
public void testBeanValidator() throws NoSuchMethodException {
Method updateStu = this.getClass().getMethod("updateStu", Stu.class);
Stu stu = new Stu();
stu.setNum(-1);
Set<ConstraintViolation<TestDataBinder>> validResult = ValidatorUtil.obtainExecutableValidator().validateParameters(this, updateStu, new Object[]{
stu});
if (!validResult.isEmpty()) {
validResult.stream().map(v -> v.getPropertyPath() + " " + v.getMessage() + ": " + v.getInvalidValue()).forEach(System.out::println);
throw new IllegalArgumentException(" Parameter error ");
}
}
Run the program , Console has no output , That is to say, the verification passed . Obviously , Just. new Coming out Stu Is not a legal model object , Therefore, it can be concluded that the verification logic in the model is not implemented , What shall I do? ? Do you still need to use it yourself Validator To use API Check ?
This involves the verification of cascading attributes , So you need to use @Valid annotation , Tell the verifier that cascade attribute verification is required , Because the default is not to check the cascade properties :
public Boolean updateStu(@Valid Stu stu){
return false;
}
Run the test program again , Console output :

Tips: :@Valid Annotations are used to validate cascading properties 、 Method parameter or method return type . For example, your attribute is still a Java Bean, You want to go deep into verifying the constraints in it , Then mark this annotation on the attribute header . in addition , By using @Valid Recursive verification can be implemented , So it can be marked in List On , Check every object in it
A digression : I believe there is a little friend who wants to ask @Valid and Spring Provided @Validated What's the difference , The answer I give is : It's not the same thing , Pure coincidence . As for why to say so , Back and Spring It's clear to you when integrating and using .
Should the annotation be written on the interface or implementation ?
Let's first add annotations to the interface , See if it will take effect :
public interface IStuService {
public void update(@Valid Stu stu);
}
public class StuServiceImpl implements IStuService{
@Override
public void update(Stu stu) {
}
}
test :
@Test
public void testBeanValidator() throws NoSuchMethodException {
Method updateStu = IStuService.class.getMethod("update",Stu.class);
Stu stu = new Stu();
stu.setNum(-1);
IStuService stuService=new StuServiceImpl();
Set<ConstraintViolation<IStuService>> validResult = ValidatorUtil.obtainExecutableValidator().validateParameters(stuService, updateStu, new Object[]{
stu});
if (!validResult.isEmpty()) {
validResult.stream().map(v -> v.getPropertyPath() + " " + v.getMessage() + ": " + v.getInvalidValue()).forEach(System.out::println);
throw new IllegalArgumentException(" Parameter error ");
}
}

In line with expectations , No problem .
Be careful
If the method is an implementation of an interface method , You must maintain the same constraints as the interface method ( The limit case : The interface has no constraint annotation , Then you can't have ), If you use it like this , Will throw an exception :
public interface IStuService {
public void update(Stu stu);
}
public class StuServiceImpl implements IStuService{
@Override
public void update(@NotNull Stu stu) {
}
}
error :
javax.validation.ConstraintDeclarationException: HV000151:
A method overriding another method must not
redefine the parameter constraint configuration,
but method StuServiceImpl#update(Stu) redefines the configuration of IStuService#update(Stu).
about override Methods , Constraint annotation should be added to the parent interface method
It is worth noting that , In the and Spring There is also a problem involved in the integrated use :@Validated Annotations should be placed on the interface ( Method ) On , Or implementation classes ( Method ) On ?
summary
This article is about Bean Validation Another classic practical scenario : Parameters of the verification method 、 Return value . Add and Spring Of AOP Integration will release more energy .
in addition , Through this article, you should be able to feel the benefits of contract programming again , All in all : Don't hard code what can be solved by contract , Life is too short , Less coding, more fun .
Reference resources
2. Bean Validation Declarative validation method parameters 、 Return value
边栏推荐
- 2022 the most NB JVM foundation to tuning notes, thoroughly understand Alibaba P6 small case
- Governance and network security of modern commercial codeless development platform
- JS filter / replace sensitive characters
- 链表合并(暑假每日一题 3)
- FPGA-HLS-乘法器(流水线对比普通仿真)
- Bubble sort - just read one
- Alamofire 框架封装与使用
- Dark horse programmer - interface test - four day learning interface test - third day - advanced usage of postman, export and import of Newman case set, common assertions, assertion JSON data, working
- Unity-笔记-ILRuntime接入
- 【运维】ssh tunneling 依靠ssh的22端口实现访问远程服务器的接口服务
猜你喜欢

C language learning notes

Software testing weekly (No. 81): what can resist negativity is not positivity, but concentration; What can resist anxiety is not comfort, but concrete.
![[paper study] source mixing and separation robot audio steganography](/img/e1/55e8f6a3e754d728fe6b685a08fdbc.png)
[paper study] source mixing and separation robot audio steganography

lc marathon 7.23

A quietly rising domestic software is too strong!

Mysql—主从复制

2022蓝帽杯初赛wp

黑马程序员-接口测试-四天学习接口测试-第三天-postman高级用法,newman例集导出导入,常用断言,断言json数据,工作原理,全局,环境变量,时间戳,请求前置脚本,关联,批量执行测试用例

如何成为一个优雅的硬件工程师?
![[attack and defense world web] difficulty Samsung 9-point introductory question (middle): ics-05, easytornado](/img/94/5b914d0ce2a2c3e1760d1b27321479.png)
[attack and defense world web] difficulty Samsung 9-point introductory question (middle): ics-05, easytornado
随机推荐
远程系统命令执行
How beautiful can VIM be configured?
Packaging and use of fmdb
1060 Are They Equal
【攻防世界WEB】难度三星9分入门题(下):shrine、lottery
Unity-笔记-ILRuntime接入
【云原生】持续集成和部署(Jenkins)
TranslucentTB 推荐
Dark horse programmer - interface test - four day learning interface test - third day - advanced usage of postman, export and import of Newman case set, common assertions, assertion JSON data, working
After Effects 教程,如何在 After Effects 中创建动画?
【运维】ssh tunneling 依靠ssh的22端口实现访问远程服务器的接口服务
sqlnet. Ora-12154 and ora-01017 connection exceptions caused by incorrect ora file settings
Go language learning - Review package, interface, file operation
ECS remote monitoring
[cloud native] install MySQL and redis services in the docker environment
Suffix expression (summer vacation daily question 4)
【攻防世界WEB】难度三星9分入门题(中):ics-05、easytornado
Umijs - data transmission between main and sub applications of Qiankun
Bean Validation规范篇----03
忘记oracle密码,如何解决