我目前正在尝试使用Hibernate Validator实现一些方法约束验证。 我已经定义了
使用 ExecutableValidator 界面进行手动验证,如Hibernate Validator documentation中所述,适用于1.-4。
与Spring的集成基本上可以使用 @Validated 来注释bean。 当我尝试使用 @Validated 在Spring容器中验证我的约束时,只有1.和2.,i。即验证方法,工作,但不是构造函数(3.和4。)。
任何想法,出了什么问题?
我创建了一个最小的工作示例: 第一个测试用例是成功的,即使它应该提出异常 第二个测试用例失败,因为在调用setter时会抛出ConstraintViolationException(实际上,异常也应该在之前抛出一行)。
我的客户bean,应该被验证(注意:setFirstName()的参数有 @NotNull 注释):
@Validated
public class Customer {
private String firstName;
private String lastName;
public Customer(@NotNull String firstName, @NotNull String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(@NotNull String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
所属的配置:
@Configuration
@ComponentScan({ "com.example.demo" })
public class MethodValidationConfig {
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}
@Bean("customer")
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public Customer customer(String firstName, String lastName) {
Customer customer = new Customer(firstName, lastName);
return customer;
}
}
然后是两个测试用例。 如前所述,第一个不会抛出异常,即使它应该。 第二个引发异常,但是在调用setter时,而不是之前。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { MethodValidationConfig.class }, loader =
AnnotationConfigContextLoader.class)
public class DemoApplicationTests {
@Autowired
private ApplicationContext applicationContext;
@Test
public void callConstructorWithInvalidParameter(){
Customer c = (Customer) applicationContext.getBean("customer", null, null);
}
@Test
public void callSetterWithInvalidParameter(){
Customer c = (Customer) applicationContext.getBean("customer", "John", "Doe");
c.setFirstName(null);
}
}
最后是我的pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.7.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>6.0.7.Final</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.2.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
</project>
答案 0 :(得分:1)
Spring验证使用AOP。默认情况下使用Spring AOP。 Spring AOP是一个代理托管组件(aka bean)的运行时AOP实现。
由于这个原因,构造函数不能通过spring AOP建议,因此验证不起作用。
对于更复杂的AOP,请考虑Aspectj。或者只是尝试将验证移到方法执行。 (Spring AOP中唯一支持的连接点)。