Spring MVC и JSR-303 hibernate условная проверка

У меня есть форма, которую я хочу проверить. Он содержит 2 адресные переменные. адрес1 всегда должен проверяться, адрес2 должен проверяться на основе некоторых условий

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

public class Address {
    @NotEmpty   
    private String street;
}

мой контроллер автоматически проверяет и связывает мой объект формы

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

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

проблема в том, что если я использую валидатор LocalValidatorFactoryBean, я не могу повторно использовать объект BinidingResult, предоставленный Spring. Привязка не будет работать, так как целевым объектом «результата» является «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, чтобы принять некоторую строку для добавления к имени поля. У вас есть лучший подход?


person mickthompson    schedule 25.10.2010    source источник


Ответы (3)


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

bindingResult.pushNestedPath("address2");
validate(form.getAddress2(), bindingResult);
bindingResult.popNestedPath();
person axtavt    schedule 25.10.2010
comment
Спасибо, axtavt, все работает. Мне интересно, лучший ли это способ сделать это, почему в @Valid нет атрибута groups и является ли концепция групп JSR-303 единственным способом добиться условной проверки - person mickthompson; 25.10.2010
comment
В @Valid есть запрос функции для групп: jira.springframework.org/browse/SPR-6373< /а> - person axtavt; 25.10.2010


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

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

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

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

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

}
person Arthur Ronald    schedule 26.10.2010
comment
Я с уважением не согласен с тем, что добавление групп в аннотацию @Valid было бы нарушением ее цели. Я рассматриваю это как улучшение. @Valid говорит, что этот объект должен быть проверен. Добавление групп фактически означает, что этот объект должен быть проверен таким образом. Нет никаких причин, по которым это же утверждение нельзя было бы применить к каскадным ассоциациям для графов объектов, а также к аргументам метода. Кроме того, спецификации должны развиваться с очевидными ценными дополнениями; Добавление групп в @Valid позволит многим фреймворкам избавиться от повторяющегося кода. Спецификации должны отдавать предпочтение практичности, а не идеализму. - person Les Hazlewood; 03.02.2011