Аннотации из javax.validation.constraints не работают - PullRequest
43 голосов
/ 06 января 2012

Какая конфигурация необходима для использования аннотаций javax.validation.constraints, таких как @Size, @NotNull и т. Д.?Вот мой код:

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class Person {
      @NotNull
      private String id;

      @Size(max = 3)
      private String name;

      private int age;

      public Person(String id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
      }
}

Когда я пытаюсь использовать его в другом классе, проверка не работает (т. Е. Объект создается без ошибки):

Person P = new Person(null, "Richard3", 8229));

Почему не 't применяются ли ограничения для id и name?Что еще мне нужно сделать?

Ответы [ 10 ]

48 голосов
/ 06 января 2012

Для проверки bean-компонента JSR-303 в Spring необходимо несколько вещей:

  1. Конфигурация пространства имен MVC для аннотаций: <mvc:annotation-driven />
  2. JAR-спецификация JSR-303: validation-api-1.0.0.GA.jar (похоже, у вас это уже есть)
  3. Реализация спецификации, такой как Hibernate Validation, которая является наиболее часто используемым примером: hibernate-validator-4.1.0.Final.jar
  4. В проверяемом компоненте аннотации проверки, либо из спецификации JAR, либо из реализации JAR (что вы уже сделали)
  5. В обработчике, который вы хотите проверить, аннотируйте объект, который вы хотите проверить, с помощью @Valid, а затем включите BindingResult в сигнатуру метода для захвата ошибок.

Пример:

@RequestMapping("handler.do")
public String myHandler(@Valid @ModelAttribute("form") SomeFormBean myForm, BindingResult result, Model model) {
    if(result.hasErrors()) {
      ...your error handling...
    } else {
      ...your non-error handling....
    }
}
28 голосов
/ 06 января 2012

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

Person person = ....;
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
Set<ConstraintViolation<Person>> violations = validator.validate(person);

Затем, повторяя набор нарушений, вы можете найти нарушения.

5 голосов
/ 06 января 2012

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

Часто используемая методика - проверка в @PrePersist и транзакция отката при использовании нескольких модификаций данных во время транзакции или другие действия при получении исключения для проверки.

Ваш код должен выглядеть следующим образом:

* * 1010
4 голосов
/ 17 августа 2015

Вы также можете просто использовать @NonNull с библиотекой lombok взамен, по крайней мере для сценария @NotNull . Подробнее: https://projectlombok.org/api/lombok/NonNull.html

1 голос
/ 22 октября 2018

Я приехал сюда через несколько лет, и я мог бы это исправить благодаря комментарию atrain выше .В моем случае мне не хватало @Valid в API , который получает объект (POJO в моем случае), который был помечен @Size.Это решило проблему.

Я сделал , а не необходимо добавить любую дополнительную аннотацию, такую ​​как @Valid или @NotBlank, к переменной, аннотированной @Size, просто это ограничениепеременная и то, что я упомянул в API ...

Класс Pojo:

...
@Size(min = MIN_LENGTH, max = MAX_LENGTH);
private String exampleVar;
...

Класс API:

...
public void exampleApiCall(@RequestBody @Valid PojoObject pojoObject){
  ...
}

Спасибо и ура

1 голос
/ 17 июля 2016

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

@CustomValidation // not called
public class MyClass {
    @Lob
    @Column(nullable = false)
    private String name;
}

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

@CustomValidation // now it works. super.
public class MyClass {
    @Lob
    @Column(nullable = false)
    @NotBlank // adding this made @CustomValidation start working
    private String name;
}

мне кажется, что поведение глючит, но достаточно легко обойти, я думаю

0 голосов
/ 17 января 2019

Отличный ответ от atrain , но, возможно, лучшее решение для перехвата исключений - использовать собственный HandlerExceptionResolver и поймать

@Override
public ModelAndView resolveException(
    HttpServletRequest aReq, 
    HttpServletResponse aRes,
    Object aHandler, 
    Exception anExc
){
    // ....
    if(anExc instanceof MethodArgumentNotValidException) // do your handle     error here
}

Тогда вы сможете сохранить ваш обработчик настолько чистым, насколько это возможно. Вам больше не нужны BindingResult, Model и SomeFormBean в myHandlerMethod.

0 голосов
/ 10 октября 2018

для параметров метода вы можете использовать Objects.requireNonNull () следующим образом: test(String str) { Objects.requireNonNull(str); } Но это проверяется только во время выполнения и выдает NPE, если равно нулю.Это как проверка предварительных условий.Но это может быть то, что вы ищете.

0 голосов
/ 18 сентября 2017

Таким образом, @Valid в интерфейсе сервиса будет работать только для этого объекта.Если у вас есть еще какие-либо проверки в иерархии объекта ServiceRequest, то у вас может быть явный запуск проверок.Вот как я это сделал:

public class ServiceRequestValidator {

      private static Validator validator;

      @PostConstruct
      public void init(){
         validator = Validation.buildDefaultValidatorFactory().getValidator();
      }

      public static <T> void validate(T t){
        Set<ConstraintViolation<T>> errors = validator.validate(t);
        if(CollectionUtils.isNotEmpty(errors)){
          throw new ConstraintViolationException(errors);
        }
     }

}

Вам необходимо иметь следующие аннотации на уровне объекта, если вы хотите запустить проверку для этого объекта.

@Valid
@NotNull
0 голосов
/ 25 мая 2017

Необходимо добавить @ Valid к каждой переменной-члена , которая также была объектом, содержащим ограничения проверки.

...