Условная проверка спящего режима Spring MVC и JSR-303 - PullRequest
9 голосов
/ 25 октября 2010

У меня есть форма, которую я хочу проверить.Он содержит 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. Я не могу повторно использовать объект BinidingResult, предоставленный Spring.Привязка не будет работать, поскольку целевой объект 'result' - это 'MyForm', а не 'Address'

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

Мне интересно, каков стандартный / чистый подход для условной проверки.

Я думал программно создать новый BindingResult в моем контроллере.

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

но тогда список ошибок, которые я получаю от bindingResultAddress2, не может быть добавлен к общему 'bindingResult', поскольку имена полей неверны («улица» вместо «address2.street») ипривязка не сработает.

Какой-то грязный подход мог бы заключаться в расширении BeanPropertyBindingResult для принятия некоторой строки для добавления к имени поля. У вас есть лучший подход?

Ответы [ 3 ]

5 голосов
/ 25 октября 2010

Стандартный подход для проверки иерархических структур заключается в использовании pushNestedPath() / popNestedPath(), хотя я не уверен, как он работает с JSR-303:

bindingResult.pushNestedPath("address2");
validate(form.getAddress2(), bindingResult);
bindingResult.popNestedPath();
1 голос
/ 25 октября 2010

Я никогда не пробовал себя, но я думаю, что правильный подход заключается в использовании групп валидаторов .

0 голосов
/ 26 октября 2010

Прежде всего, давайте посмотрим @javax.validation.Valid API

Отметить ассоциацию как каскадную .Связанный объект будет проверен каскадом.

Когда Spring Framework использует @Valid в качестве маркера для проверки своих объектов команд, это нарушает его назначение.Вместо этого Spring должен создать собственную особую аннотацию, в которой указаны группы, которые должны быть проверены.

К сожалению, вам следует использовать собственный API-интерфейс Validator Spring, если вам нужно проверить некоторые группыбыть реализован как

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()); 
        }
    }

}
...