[英]Spring MVC and JSR 303 - Manual Validation
我正在使用Spring MVC 3和JSR 303.我有一个表单支持对象,其中包含不同类型的bean。 根据请求参数值,我必须选择一个bean来验证和保存。 我无法使用@Valid
进行验证,因为要运行时才知道要验证的bean。
我能够向控制器注入一个javax.validation.Validator
,但我不知道如何用它来验证bean并在“Spring方式” BindingResult/Error
任何错误存储在BindingResult/Error
中。
由于请求映射,我需要在处理程序方法而不是initBinder
方法中执行此操作。
[编辑]
我在validate(Object, Errors)
遇到的问题是它无法识别嵌套bean。 要验证的bean是通过foo.getBar()。getBean()访问的,其中foo是表单后备对象。 当我validate(foo.getBar().getBean(), errors)
,我收到以下错误消息。
JSR-303 validated property 'property-name' does not have a corresponding accessor for Spring data binding
以前有人做过这样的事吗? 谢谢。
是的,你正在寻找的魔法类是org.springframework.validation.beanvalidation.SpringValidatorAdapter
该类获取一个注入其中的javax.validation.Validator,并包含代码,顾名思义,将输出“调整”回熟悉的Errors
对象。 当你将@Valid
放在方法参数上时,它就是在内部用来进行处理的。
您可以通过在调度程序servlet中添加显式LocalValidatorFactoryBean
来直接获取它们。 只需注入一个实例作为标准Spring Validator接口的实例,并像使用任何'pre jsr-303'弹簧验证提供程序一样使用它。
只是一个猜测,但你有没有尝试过
errors.pushNestedPath("bar.bean"); // Path to the nested bean
validate(foo.getBar().getBean(), errors)
errors.popNestedPath();
这就是BindingResult
通常用于验证嵌套bean的方式。
我看到这样做的方式是使用标准的JSR-303验证器(无论你注入的是什么)来获取违规(即Set<ConstraintViolaion<T>>
)
然后使用类似于LocalValidatorFactoryBean内部的代码来转换这些违规和Spring错误:
public static <T> void convert(Errors errors, Collection<ConstraintViolation<T>> violations) {
for (ConstraintViolation<?> violation : violations) {
String field = violation.getPropertyPath().toString();
FieldError fieldError = errors.getFieldError(field);
if (fieldError == null || !fieldError.isBindingFailure()) {
errors.rejectValue(field, violation.getConstraintDescriptor().getAnnotation().annotationType()
.getSimpleName(), getArgumentsForConstraint(errors.getObjectName(), field, violation
.getConstraintDescriptor()), violation.getMessage());
}
}
}
private static Object[] getArgumentsForConstraint(String objectName, String field,
ConstraintDescriptor<?> descriptor) {
List<Object> arguments = new LinkedList<Object>();
String[] codes = new String[] { objectName + Errors.NESTED_PATH_SEPARATOR + field, field };
arguments.add(new DefaultMessageSourceResolvable(codes, field));
arguments.addAll(descriptor.getAttributes().values());
return arguments.toArray(new Object[arguments.size()]);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.