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.

Siergiej Tachenov
źródło
2
Może być interesujący: stackoverflow.com/questions/18911154/…
Wim Deblauwe
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.

František Hartman
źródło
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;

}
zhuhang.jasper
źródło
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

Lebecca
źródło
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.

Zelin Zhu
źródło