Unterschied zwischen @Valid und @Validated im Frühjahr

106

Spring unterstützt zwei verschiedene Validierungsmethoden: Spring-Validierung und JSR-303-Bean-Validierung. Beide können verwendet werden, indem ein Spring-Validator definiert wird, der an andere Delegatoren delegiert, einschließlich des Bean-Validators. So weit, ist es gut.

Wenn Sie jedoch Methoden mit Anmerkungen versehen, um tatsächlich eine Validierung anzufordern, ist dies eine andere Geschichte. Ich kann so kommentieren

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

oder so

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

Hier ist @Valid javax.validation.Valid und @Validated ist org.springframework.validation.annotation.Validated . Die Dokumente für letztere sagen

Variante von JSR-303 Valid, die die Angabe von Validierungsgruppen unterstützt. Entwickelt für die bequeme Verwendung mit der JSR-303-Unterstützung von Spring, jedoch nicht JSR-303-spezifisch.

Das hilft nicht viel, weil es nicht genau sagt, wie es anders ist. Wenn überhaupt. Beide scheinen für mich ziemlich gut zu funktionieren.

Sergei Tachenov
quelle
2
Könnte
Wim Deblauwe
4
"Unterstützung der Spezifikation von Validierungsgruppen" ist eine sehr explizite Aussage.
Ein besserer Oliver
Ich sollte denken, dass Valid eng mit JSR 303-Validierungen (NotNull usw.) verbunden ist. Sie können andere Validierungen / Gruppen erstellen und diese in Validiert einchecken lassen.
Atul
@zeroflagL, stimmt, aber da ich es nie benutzt habe, habe ich den Punkt verpasst und mich stattdessen auf den Teil "nicht JSR-303-spezifisch" fixiert. Jetzt ist es klar.
Sergei Tachenov

Antworten:

83

Wie Sie aus der Dokumentation zitiert haben, @Validatedwurde hinzugefügt, um "Validierungsgruppen" zu unterstützen, dh eine Gruppe von Feldern in der validierten Bean. Dies kann in mehrstufigen Formularen verwendet werden, in denen Sie im ersten Schritt Name, E-Mail usw. und in den folgenden Schritten andere Felder überprüfen können.

Der Grund, warum dies nicht in die @ValidAnnotation aufgenommen wurde, liegt darin, dass es mithilfe des Java-Community-Prozesses (JSR-303) standardisiert wird, was einige Zeit in Anspruch nimmt, und Spring-Entwickler wollten den Benutzern ermöglichen, diese Funktionalität früher zu verwenden.

Gehen Sie zu diesem Jira-Ticket, um zu sehen, wie die Anmerkung entstanden ist.

František Hartman
quelle
112

Eine direktere Antwort. Für diejenigen, die noch nicht wissen, was in aller Welt "Validierungsgruppe" ist .

Verwendung zur @ValidValidierung

Regler:

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

Formularobjekt:

public class Account {

    @NotBlank
    private String username;

    @Email
    @NotBlank
    private String email;

}

Verwendung für @ValidatedValidierungsgruppen
Quelle: http://blog.codeleak.pl/2014/08/validation-groups-in-spring-mvc.html

Regler:

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

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

Formularobjekt:

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
quelle
danke @ Zhuhang.jasper für die ausführliche Erklärung mit großer Einfachheit.
Gautam Tyagi
Genau das habe ich in den letzten 2 Stunden gesucht, danke @ Zhuhang.jasper
Shady Hussein
danke @zhuhang. habe danach gesucht.
Vishnu Dahatonde
4

Im Beispiel Code-Schnipsel der Frage, @Validund @Validatedmachen keinen Unterschied. Wenn das @RequestBodyjedoch mit einem ListObjekt oder einem Zeichenfolgenwert versehen ist @RequestParam, wird die Validierung nicht wirksam.

Wir können die @ValidatedValidierungsfunktion auf Methodenebene verwenden, damit es funktioniert. Um dies zu erreichen, ist es wichtig, @Validateddie Klasse zu platzieren. Dies kann ein weiterer wichtiger Unterschied zwischen @Validund @Validatedim Frühjahrsrahmen sein.

Erfrischung

Lebecca
quelle
Können Sie erklären, warum die Anmerkung keine Auswirkungen auf ListObjekte hat? Ich gehe davon aus, dass dies auch für andere Sammlungen nicht funktioniert wie Map? Vielleicht könnten Sie mir eine ausführlichere Erklärung in meiner Frage geben: stackoverflow.com/questions/60167961/…
Theiaz
1
@ Theiaz Wie du willst
Lebecca
1

Außerdem können Sie nur für @Valideine Domäne / ein Feld eine verschachtelte Validierung beantragen , nicht für eine @validated.

Zelin Zhu
quelle