我正在尝试使用 @ConvertGroup
对我的spring启动项目进行一些级联验证,但它似乎不起作用 . 谁能告诉我我做错了什么?
我为这个问题创建了一个精简的项目 .
你可以在这里查看:https://github.com/ericbv/cascadingValidationConvertGroupSpringBoot
我有以下表格的DTO:
父母Dto
@GroupSequenceProvider(ParentGroupSequenceProvider.class)
public class ParentDto {
@Valid
@ConvertGroup(from= CreateChild.class , to = Creation.class)
private ChildDto childDto;
private boolean createChild;
public ChildDto getChildDto() {
return childDto;
}
public void setChildDto(ChildDto childDto) {
this.childDto = childDto;
}
public boolean isCreateChild() {
return createChild;
}
public void setCreateChild(boolean createChild) {
this.createChild = createChild;
}
}
根据我的理解,如果在验证父级时存在CreateGroup组,则ConvertGroup注释应在子验证中传递CreationGroup . (该组将由ParentGroupSequenceProvider提供 .
和子对象:
public class ChildDto {
@NotEmpty(groups = Creation.class)
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
如果存在“创建”组,则名称不能为空 . 我已经通过将 @GroupSequence({ChildDto.class,Creation.class})
添加到此类的顶部进行了测试,这导致了验证错误 .
父DTO具有以下组序列提供程序:
public class ParentGroupSequenceProvider implements DefaultGroupSequenceProvider<ParentDto> {
static Logger log = Logger.getLogger(ParentGroupSequenceProvider.class.getName());
@Override
public List<Class<?>> getValidationGroups(ParentDto parentDto) {
List<Class<?>> sequence = new ArrayList<Class<?>>();
/*
* must be added to the returned list so that the validator gets to know
* the default validation rules, at the very least.
*/
sequence.add(ParentDto.class);
if (parentDto == null)
return sequence;
/*
* Here, we can implement a certain logic to determine what are the additional group of rules
* that must be applied.
*/
if(parentDto.isCreateChild()){
sequence.add(CreateChild.class);
log.info("Added CreateChild to groups");
}
return sequence;
}
}
如果创建布尔值为true,则此序列提供程序将添加creatChild组 .
我通过使用 @NotEmpty(groups = CreateChild.class)
向parentDto添加字符串属性来测试groupSequenceProvider . 这引发了验证错误,因此我知道该组已提供 .
控制器mehtod:
@RequestMapping(value = "/test",method = RequestMethod.POST)
public String doPost(@Valid ParentDto parentDto, BindingResult bindingResult){
if(bindingResult.hasErrors()){
bindingResult.getAllErrors().forEach( error-> log.error(error));
return "redirect: /error";
}else{
return "redirect: /";
}
}
问题是当表单提交并且createChild为true时,不验证childDto中的name属性 .
我错过了什么?
Pom文件如下:
<?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.test</groupId>
<artifactId>valid-testing</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>valid-testing</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
1 回答
Documentation bean验证
@GroupSequence
状态:@GroupSequenceProvider
也是如此 . 在您的示例中,@GroupSequenceProvider
仅影响其目标ParentDto
类而不影响ChildDto
. 因此ChildDto
只能看到默认组 . 因此,组转换规则必须是:这解决了当前场景的问题,但又产生了另一个问题:在另一个场景中,当您使用
Default
group验证ParentDto
时(当createChild
为false时),它仍然会转换为Creation
为Creation
组 . 因此,只有使用groups = Creation.class
注释的验证才会得到验证,我认为这不是您打算做的(在该场景中) .通常,我不建议您当前尝试验证类的方式 . 使用
Validator
并根据createChild
字段的值手动调用不同组的验证或在ParentController
中写入两个不同的方法(一个用于创建子项,另一个用于另一个案例)并使用@Validated和合适的组 .第一种方式如下:
并在
ParentDto
: