这里有新的Spring开发人员。我搜索了SO和春季文档,但无法解决这个问题。
我正在尝试使用Spring Validation将任何适用的Validator
实现应用于任意对象,方法是注入所有已注册的验证器,并通过调用supports()
然后有条件地validate()
进行迭代。这有效,除了它产生重复的验证消息,因为JSR-303约束注释被验证两次 - 一次由jsr303Validator
验证,再由mvcValidator
验证。
我尝试调用所有验证器并在之后删除重复的错误,但equals()
上的ObjectError
实现无法正常工作(它会使条目具有相同的错误代码和消息)。
验证器实施:
import org.springframework.validation.BindException;
import org.springframework.validation.Validator;
@Service
class ObjectValidatorImpl {
private final Validator[] validators;
public ObjectValidatorImpl(Validator[] validators) {
this.validators = validators;
}
public void validate(Object obj) throws BindException {
// Container for holding any validation errors that are found
BindException errors = new BindException(obj, obj.getClass().getName());
for (Validator validator : validators) {
if (validator.supports(obj.getClass())) {
validator.validate(obj, errors);
}
}
if (errors.hasErrors()) {
throw errors;
}
}
}
显示错误的示例程序:
@SpringBootApplication
public class ValidationTestApplication implements CommandLineRunner {
@Autowired
private ObjectValidator objectValidator;
public static void main(String[] args) {
SpringApplication.run(ValidationTestApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
try {
objectValidator.validate(new TestObject());
}
catch (BindException ex) {
System.out.println(ex);
}
}
}
class TestObject {
@NotEmpty
String name;
}
错误输出示例:
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'validationtest.TestObject' on field 'name': rejected value [null]; codes [NotEmpty.validationtest.TestObject.name,NotEmpty.name,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [validationtest.TestObject.name,name]; arguments []; default message [name]]; default message [may not be empty]
Field error in object 'validationtest.TestObject' on field 'name': rejected value [null]; codes [NotEmpty.validationtest.TestObject.name,NotEmpty.name,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [validationtest.TestObject.name,name]; arguments []; default message [name]]; default message [may not be empty]
请注意jsr303Validator
和mvcValidator
报告两次“名称不能为空”错误。
Gradle依赖项:
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-validation')
compile('org.springframework.boot:spring-boot-starter-web')
runtime("com.h2database:h2")
}
解决此类情况的正确(最弹性?)方法是什么?感觉它是一个类路径配置问题,我应该避免在同一个项目中同时使用两个验证器,但是这个代码位于一个共享库中,可能与Spring Web MVC一起使用,也可能不使用,我不知道如何防止这种情况
答案 0 :(得分:0)
这不是应该发生的事吗?
您为该对象注册了多个验证器,因此当您遍历所有验证器并请求验证消息时,您将获得重复,因为它们都是相似的。