Подтвердить что ты не робот

Вручную вызовите Spring Проверка аннотации

Я выполняю большую часть нашей проверки с помощью Hibernate и Spring Аннотации, подобные этому:

public class Account {
    @NotEmpty(groups = {Step1.class, Step2.class})
    private String name;

    @NotNull(groups = {Step2.class})
    private Long accountNumber;

    public interface Step1{}
    public interface Step2{}
}

И затем в контроллере он вызывает в аргументах:

public String saveAccount(@ModelAttribute @Validated({Account.Step1.class}) Account account, BindingResult result) {
   //some more code and stuff here
   return "";
}

Но я хотел бы выбрать группу, используемую на основе некоторой логики в методе контроллера. Есть ли способ вызвать проверку вручную? Что-то вроде result = account.validate(Account.Step1.class)?

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

4b9b3361

Ответ 1

Следуя шагу дальше, чем Jaiwo99 в его ответе:

// org.springframework.validation.SmartValidator - implemented by
//     LocalValidatorFactoryBean, which is funny as it is not a FactoryBean per se (just saying)
@Autowired
SmartValidator validator;

public String saveAccount(@ModelAttribute Account account, BindingResult result) {
    // ... custom logic
    validator.validate(account, result, Account.Step1.class);
    if (result.hasErrors()) {
        // ... on binding or validation errors
    } else {
        // ... on no errors
    }
    return "";
}

И обязательная ссылка на SmartValidator JavaDoc, если вы заинтересованы.

Ответ 2

Вот пример кода из JSR 303 spec

Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

Driver driver = new Driver();
driver.setAge(16);
Car porsche = new Car();
driver.setCar(porsche);


Set<ConstraintViolation<Driver>> violations = validator.validate( driver );

Итак, да, вы можете просто получить экземпляр валидатора из валидатора factory и запустить проверку самостоятельно, а затем проверить, есть ли нарушения или нет. Вы можете увидеть в javadoc для Validator, что он также примет массив групп для проверки.

Очевидно, что это использует проверку JSR-303 напрямую вместо проверки Spring, но я верю, что Spring аннотации проверки будут использовать JSR-303, если он найден в пути к классам

Ответ 3

Если у вас все правильно настроено, вы можете сделать это:

@Autowired
Validator validator;

Затем вы можете использовать его для проверки объекта.

Ответ 4

А также:

@Autowired
@Qualifier("mvcValidator")
Validator validator;

...
violations = validator.validate(account);

Ответ 5

Добавив ответ @digitaljoel, вы можете выбросить исключение ConstraintViolationException после получения набора нарушений.

Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
        Set<ConstraintViolation<NotionalProviderPaymentDTO>> violations = validator.validate( notionalProviderPaymentDTO );

        if(!violations.isEmpty()) {
            throw new ConstraintViolationException(violations);
        }

Вы можете создать свой собственный сопоставитель исключений, который будет обрабатывать ConstraintViolationException и отправлять сообщения об ошибках клиенту.