我一个形式我想验证。它包含2个地址变量。地址1一直被验证,地址2具有基于一些条件进行验证

public class MyForm {
    String name;
    @Valid Address address1;
    Address address2;
 }

public class Address {
    @NotEmpty   
    private String street;
}

我的控制器自动验证和结合我的形式OBJ

@RequestMapping(...)
public ModelAndView edit(
        @ModelAttribute("form")
        @Valid
        MyForm form,
        BindingResult bindingResult,
        ...)

        if(someCondition) {
            VALIDATE form.address2 USING JSR 303

的问题是,如果我使用LocalValidatorFactoryBean验证我不能重用Spring提供的BinidingResult对象。绑定不会工作作为“结果”的目标对象是“MyForm的”,而不是“地址”

validate(form.getAddress2(), bindingResult)   //won't work

我不知道有什么标准/清洁方法进行条件验证。

我想在编程创建我的控制器新BindingResult。

final BindingResult bindingResultAddress2 = new BeanPropertyBindingResult(address2, "form");
validate(form.getAddress2(), bindingResultAddress2);

但随后的错误我从bindingResultAddress2获取列表不能被添加到一般的“bindingResult”作为字段名是不正确(“街道”,而不是“address2.street”)和结合不会工作

有些脏的方法是延长BeanPropertyBindingResult接受一些字符串追加到字段名..你有更好的方法吗?

有帮助吗?

解决方案

有关验证层次结构的标准方法是使用pushNestedPath() / popNestedPath(),虽然我不知道它是如何发挥与JSR-303:

bindingResult.pushNestedPath("address2");
validate(form.getAddress2(), bindingResult);
bindingResult.popNestedPath();

其他提示

我从来没有尝试过自己,但我认为正确的做法是使用的验证组

首先,让我们来看看 @ javax.validation.Valid API

  

<强>标记的关联作为级联即可。相关的对象将通过级联进行验证。

当Spring框架使用@Valid的作为标记以验证其命令对象,它破坏了目的。春节应改为创建自己的特定注释指定哪个应验证的组。

不幸的是,你应该,如果你需要验证某些群体使用Spring本地验证API

public void doSomething(Command command, Errors errors) {
    new BeanValidationValidator(SomeUserCase.class, OtherUserCase.class)
        .validate(command, errors);

    if(errors.hasErrors()) {

    } else {

    }
}

BeanValidationValidator可以实现为

public class BeanValidationValidator implements Validator {

    javax.validation.Validator validator = ValidatorUtil.getValidator();

    private Class [] groups;

    public BeanValidationValidator(Class... groups) {
        this.groups = groups;
    }

    public void validate(Object command, Errors errors) {
        Set<ConstraintViolation<Object>> constraintViolationSet = validator.validate(command, groups);

        for(ConstraintViolation<Object> constraintViolation: constraintViolationSet) {
            errors.rejectValue(constraintViolation.getPropertyPath().toString(), null, constraintViolation.getMessage()); 
        }
    }

}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top