我使用的是Spring MVC 3和JSR303。我有一个形式的背面对象,其中包含不同类型的bean。根据请求参数值的不同,我必须选择一个bean来验证并保存。我不能使用 @Valid 为了验证,因为要验证的bean直到运行时才知道。

我能够注入 javax.validation.Validator 到控制器,但我不确定如何用它验证豆并将任何错误存储在 BindingResult/Error 以“春天的方式”。

我需要在处理程序方法中做到这一点,而不是 initBinder 方法,由于请求映射。

编辑

我遇到的问题 validate(Object, Errors) 是它无法识别嵌套的豆。通过foo.getbar()。getBean()访问要验证的bean,其中foo是表单备份对象。当我做 validate(foo.getBar().getBean(), errors), ,我会收到以下错误消息。

JSR-303 validated property 'property-name' does not have a corresponding accessor for Spring data binding

有人做过这样的事情吗?谢谢。

有帮助吗?

解决方案

只是一个猜测,但是你尝试过

 errors.pushNestedPath("bar.bean"); // Path to the nested bean
 validate(foo.getBar().getBean(), errors)
 errors.popNestedPath();

这就是如何 BindingResult 通常用于验证嵌套豆。

其他提示

是的,您要寻找的魔术课是 org.springframework.validation.beanvalidation.SpringValidatorAdapter

此类将javax.validation.validator注入其中,并顾名思义,其中包含代码,将输出“调整”回到熟悉的 Errors 目的。当您放置时,这就是内部用于处理处理的方法 @Valid 在方法参数上。

您可以通过添加显式直接获得它们 LocalValidatorFactoryBean 在您的调度员servlet中。只需将其作为标准弹簧验证器接口的实例注入实例,然后像您一样使用它的任何“ pre jsr-303”弹簧验证提供商。

我所看到的方式是使用标准的JSR-303验证器(无论您已经注入什么)来违反(即 Set<ConstraintViolaion<T>>)

然后使用与LocalValidatorFactoryBean中类似的代码进行转换,以在这些违规和弹簧错误之间转换:

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归因
不隶属于 StackOverflow
scroll top