Różnica między @Valid i @Validated in Spring


110

Spring obsługuje dwie różne metody walidacji: walidację Spring i walidację bean JSR-303. Oba mogą być używane przez zdefiniowanie walidatora Spring, który deleguje do innych delegatorów, w tym walidatora bean. Na razie w porządku.

Ale kiedy opisujemy metody, aby faktycznie zażądać walidacji, to już inna historia. Mogę tak opisywać

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

lub w ten sposób

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

Tutaj @Valid to javax.validation.Valid , a @Validated to org.springframework.validation.annotation.Validated . Dokumentacja tego ostatniego mówi

Wariant Valid JSR-303, wspierający specyfikację grup walidacyjnych. Zaprojektowany do wygodnego użytkowania ze wsparciem Springa JSR-303, ale nie specyficznym dla JSR-303.

co niewiele pomaga, ponieważ nie mówi dokładnie, jak to się różni. Jeżeli w ogóle. Wydaje mi się, że oba działają całkiem nieźle.



4
„wspieranie specyfikacji grup walidacyjnych” jest bardzo wyraźnym stwierdzeniem.
lepszy oliver

Powinienem pomyśleć, że Valid jest ściśle powiązany z walidacjami JSR 303 (NotNull itp.). Podczas gdy możesz tworzyć inne walidacje / grupy i mieć je sprawdzone w Validated.
Atul

@zeroflagL, to prawda, ale ponieważ nigdy go nie używałem, przegapiłem sedno i zamiast tego skupiłem się na części „nie specyficznej dla JSR-303”. Teraz jest jasne.
Siergiej Tachenov

Odpowiedzi:


84

Jak cytowałeś z dokumentacji, @Validated została dodana do obsługi "grup walidacyjnych", czyli grupy pól w walidowanym beanie. Można to wykorzystać w wieloetapowych formularzach, w których można zweryfikować imię i nazwisko, adres e-mail itp. W pierwszym kroku, a następnie inne pola w kolejnych krokach.

Powód, dla którego nie został dodany @Valid adnotacji, jest to, że jest on ustandaryzowany przy użyciu procesu społeczności java (JSR-303), co zajmuje trochę czasu, a programiści Spring chcieli umożliwić ludziom korzystanie z tej funkcji wcześniej.

Przejdź do tego biletu Jira, aby zobaczyć, jak powstała adnotacja.


118

Bardziej prosta odpowiedź. Dla tych, którzy wciąż nie wiedzą, co to na ziemi jest „grupa walidacyjna” .

Użycie dla @Valid walidacji

Kontroler:

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

Obiekt formularza:

public class Account {

    @NotBlank
    private String username;

    @Email
    @NotBlank
    private String email;

}

Wykorzystanie dla @ValidatedValidation Group
Źródło: http://blog.codeleak.pl/2014/08/validation-groups-in-spring-mvc.html

Kontroler:

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

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

Obiekt formularza:

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;

}

dzięki @ Zhuhang.jasper za szczegółowe wyjaśnienie z wielką prostotą.
Gautam Tyagi

To jest dokładnie to, czego szukałem przez ostatnie 2 godziny, dzięki @ Zhuhang.jasper
Shady Hussein

4

W przykładzie fragmenty kodu pytania @Validi @Validatednie ma znaczenia. Ale jeśli @RequestBodyjest opatrzony adnotacją Listobiektem lub jest wartością ciągu z adnotacją@RequestParam , walidacja nie odniesie skutku.

Możemy użyć @Validatedmożliwości walidacji na poziomie metody, aby to zadziałało. Aby to osiągnąć, kluczową kwestią jest umieszczenie @Validatedna zajęciach. Może to być kolejna ważna różnica między @Validi @Validatedw ramach wiosennych.

Odniesienie


Czy możesz wyjaśnić, dlaczego adnotacja nie ma wpływu na Listobiekty? Zakładam, że to też nie zadziała w przypadku innych kolekcji jak Map? Może mógłbyś dać mi bardziej szczegółowe wyjaśnienie w moim pytaniu: stackoverflow.com/questions/60167961/ ...
Theiaz

1
@Theiaz Jak sobie życzysz
Lebecca

1

poza tym możesz ubiegać się tylko @Validw domenie / polu o zagnieżdżoną walidację, a nie z rozszerzeniem @validated.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.