Разница между @Valid и @Validated весной

110

Spring поддерживает два разных метода проверки: проверка Spring и проверка bean-компонентов JSR-303. Оба могут использоваться, определяя валидатор Spring, который делегирует другим делегатам, включая валидатор bean. Все идет нормально.

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

@RequestMapping(value = "/object", method = RequestMethod.POST)
public @ResponseBody TestObject create(@Valid @RequestBody TestObject obj, BindingResult result) {

или как это

@RequestMapping(value = "/object", method = RequestMethod.POST)
public @ResponseBody TestObject create(@Validated @RequestBody TestObject obj, BindingResult result) {

Здесь @Valid - это javax.validation.Valid , а @Validated - это org.springframework.validation.annotation.Validated . В документации для последнего говорится

Вариант Valid JSR-303, поддерживающий спецификацию групп валидации. Разработан для удобного использования с поддержкой Spring JSR-303, но не специфичен для JSR-303.

что не очень помогает, потому что не говорит точно, чем все отличается. Если вообще. Мне кажется, оба работают нормально.

Сергей Таченов
источник
2
Может быть интересно: stackoverflow.com/questions/18911154/…
Wim Deblauwe
4
«поддержка спецификации групп проверки» - очень явное утверждение.
a better oliver
Я думаю, что Valid тесно связан с проверками JSR 303 (NotNull и т. Д.). Принимая во внимание, что вы можете создать другие проверки / группы и проверить их в Validated.
Атул,
@zeroflagL, правда, но поскольку я никогда не использовал его, я упустил суть и вместо этого сосредоточился на части, «не относящейся к JSR-303». Теперь ясно.
Сергей Таченов

Ответы:

84

Как вы процитировали из документации, @Validatedбыла добавлена ​​поддержка «групп проверки», то есть группы полей в проверяемом компоненте. Это можно использовать в многоступенчатых формах, где вы можете проверить имя, адрес электронной почты и т. Д. На первом этапе, а затем в других полях на следующем этапе (этапах).

Причина, по которой это не было добавлено в @Validаннотацию, заключается в том, что он стандартизирован с использованием процесса сообщества Java (JSR-303), который требует времени, и разработчики Spring хотели, чтобы люди могли использовать эту функцию раньше.

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

Франтишек Хартман
источник
117

Более прямой ответ. Для тех, кто еще не знает, что такое «группа проверки» .

Использование для @Validпроверки

Контроллер:

@RequestMapping(value = "createAccount")
public String stepOne(@Valid Account account) {...}

Объект формы:

public class Account {

    @NotBlank
    private String username;

    @Email
    @NotBlank
    private String email;

}

Использование для @Validatedгруппы проверки
Источник: http://blog.codeleak.pl/2014/08/validation-groups-in-spring-mvc.html

Контроллер:

@RequestMapping(value = "stepOne")
public String stepOne(@Validated(Account.ValidationStepOne.class) Account account) {...}

@RequestMapping(value = "stepTwo")
public String stepTwo(@Validated(Account.ValidationStepTwo.class) Account account) {...}

Объект формы:

public class Account {

    @NotBlank(groups = {ValidationStepOne.class})
    private String username;

    @Email(groups = {ValidationStepOne.class})
    @NotBlank(groups = {ValidationStepOne.class})
    private String email;

    @NotBlank(groups = {ValidationStepTwo.class})
    @StrongPassword(groups = {ValidationStepTwo.class})
    private String password;

    @NotBlank(groups = {ValidationStepTwo.class})
    private String confirmedPassword;

}
zhuhang.jasper
источник
спасибо @ Zhuhang.jasper за подробное и простое объяснение.
Гаутам Тьяги
Это именно то, что я искал последние 2 часа, спасибо @ Zhuhang.jasper
Shady Hussein
4

В примере фрагменты кода вопроса @Validи @Validatedбез разницы. Но если @RequestBodyаннотируется Listобъектом или является строковым значением, аннотированным @RequestParam, проверка не вступит в силу.

Мы можем использовать @Validatedвозможность проверки на уровне метода, чтобы заставить его работать. Чтобы добиться этого, ключевым моментом является размещение @Validatedв классе. Это может быть еще одно важное различие между @Validи @Validatedв весеннем рамках.

Ссылка

Лебекка
источник
Не могли бы вы объяснить, почему аннотация не действует на Listобъекты? Я предполагаю, что это также не будет работать для других коллекций, например Map? Возможно, вы могли бы дать мне более подробное объяснение в моем вопросе: stackoverflow.com/questions/60167961/…
Theiaz
1
@Theiaz Как пожелаешь
Лебекка
1

помимо вышеуказанного, вы можете подать заявку только @Validна домен / поле для вложенной проверки, но не с расширением @validated.

Зелин Чжу
источник