Вручную вызовите 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, но что-то, чего я хочу избежать, я бы предпочел просто использовать аннотации для самих переменных класса.
Ответы
Ответ 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 и отправлять сообщения об ошибках клиенту.