Java 将JSR-303验证错误转换为Spring';绑定结果
我在Spring控制器中有以下代码:Java 将JSR-303验证错误转换为Spring';绑定结果,java,spring,validation,spring-mvc,bean-validation,Java,Spring,Validation,Spring Mvc,Bean Validation,我在Spring控制器中有以下代码: @Autowired 私有javax.validation.Validator验证程序; @RequestMapping(value=“/submit”,method=RequestMethod.POST) 公共字符串提交表单(自定义表单){ 设置错误=validator.validate(表单); ... } 是否可以将错误映射到Spring的BindingResult对象,而无需手动检查所有错误并将其添加到BindingResult?大概是这样的: /
@Autowired
私有javax.validation.Validator验证程序;
@RequestMapping(value=“/submit”,method=RequestMethod.POST)
公共字符串提交表单(自定义表单){
设置错误=validator.validate(表单);
...
}
是否可以将错误
映射到Spring的BindingResult
对象,而无需手动检查所有错误并将其添加到BindingResult
?大概是这样的:
// NOTE: this is imaginary code
BindingResult bindingResult = BindingResult.fromConstraintViolations(errors);
我知道可以用@Valid
注释CustomForm
参数,并让Spring将BindingResult
作为另一个方法的参数,但在我的例子中,这不是一个选项
// I know this is possible, but doesn't work for me
public String submitForm(@Valid CustomForm form, BindingResult bindingResult) {
...
}
一种更简单的方法是使用Spring的抽象
org.springframework.validation.Validator
,相反,您可以通过在上下文中使用这个bean来获得验证器:
<bean id="jsr303Validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
@Autowired @Qualifier("jsr303Validator") Validator validator;
Spring使用SpringValidatorAdapter将javax.validation.ConstraintViolation对象转换为ObjectError或FieldError对象,如绑定结果中所示。 BindStatus然后使用消息源(如web应用程序上下文本身)来转换错误。 简而言之,您可以:
SpringValidatorAdapter springValidator = new SpringValidatorAdapter(validator);
BindingResult bindingResult= new BeanPropertyBindingResult(myBeanToValidate, "myBeanName");
springValidator.validate(myBeanToValidate, bindingResult);
这在编写单元测试时更容易,因为您甚至不需要创建Spring上下文。扩展Kristiaan的答案,出于测试目的,不需要创建Spring上下文来使用Spring的bindingResult进行验证。以下是一个例子:
public class ValidatorTest {
javax.validation.Validator javaxValidator = Validation.buildDefaultValidatorFactory().getValidator();
org.springframework.validation.Validator springValidator = new SpringValidatorAdapter(javaxValidator);
@Test
public void anExampleTest() {
JSR303AnnotatedClassToTest ctt = new JSR303AnnotatedClassToTest( ..init vars..)
... test setup...
WebDataBinder dataBinder = new WebDataBinder(ctt);
dataBinder.setValidator(springValidator);
dataBinder.validate();
BindingResult bindingResult = dataBinder.getBindingResult();
... test analysis ...
}
}
这种方法不需要提前创建绑定结果,dataBinder会为您构建正确的绑定结果 @RequestMapping(value=“/submit”,method=RequestMethod.POST)
公共字符串提交表单(自定义表单){
设置错误=validator.validate(表单);
BindingResult BindingResult=toBindingResult(错误,形式,“形式”);
...
}
私有BindingResult到BindingResult(ConstraintViolationException e、对象对象、字符串对象名){
BindingResult BindingResult=新BeanPropertyBindingResult(对象,对象名);
新的AddConstraintViolationsToErrors().addConstraintViolations(例如getConstraintViolations(),bindingResult);
返回绑定结果;
}
私有静态类AddConstraintViolationsToErrors扩展了SpringValidatorAdapter{
public AddConstraintViolationsToErrors(){
super(Validation.buildDefaultValidatorFactory().getValidator());//实际未使用验证程序
}
@SuppressWarnings({“rawtypes”,“unchecked”})
公共void addConstraintViolations(集合>冲突、错误){
//使用原始类型,因为processConstraintViolations特别需要ConstraintViolation
super.processConstraintViolations((设置)冲突、错误);
}
}
与此问题的其他答案不同,此解决方案处理已存在
setThank的情况!这肯定更简洁。我没有看到接受BindingResulti的方法validate如果没有看到接受绑定结果的validate方法,这意味着您的验证器验证器是javax.validation.Validator。将其更改为org.springframework.validation.Validator,您就会没事了。无需更改bean定义。
public class ValidatorTest {
javax.validation.Validator javaxValidator = Validation.buildDefaultValidatorFactory().getValidator();
org.springframework.validation.Validator springValidator = new SpringValidatorAdapter(javaxValidator);
@Test
public void anExampleTest() {
JSR303AnnotatedClassToTest ctt = new JSR303AnnotatedClassToTest( ..init vars..)
... test setup...
WebDataBinder dataBinder = new WebDataBinder(ctt);
dataBinder.setValidator(springValidator);
dataBinder.validate();
BindingResult bindingResult = dataBinder.getBindingResult();
... test analysis ...
}
}