Was zeigt die Annotation @Valid im Frühjahr an?

87

Im folgenden Beispiel ist der ScriptFileParameter mit einer @ValidAnmerkung gekennzeichnet.

Was macht @ValidAnnotation?

@RequestMapping(value = "/scriptfile", method = RequestMethod.POST)    
public String create(@Valid ScriptFile scriptFile, BindingResult result, ModelMap modelMap) {    
    if (scriptFile == null) throw new IllegalArgumentException("A scriptFile is required");        
    if (result.hasErrors()) {        
        modelMap.addAttribute("scriptFile", scriptFile);            
        modelMap.addAttribute("showcases", ShowCase.findAllShowCases());            
        return "scriptfile/create";            
    }        
    scriptFile.persist();        
    return "redirect:/scriptfile/" + scriptFile.getId();        
}    
Gary Ford
quelle

Antworten:

63

Es dient zu Validierungszwecken.

Validierung Es ist üblich, ein Modell zu validieren, nachdem Benutzereingaben daran gebunden wurden. Spring 3 bietet Unterstützung für die deklarative Validierung mit JSR-303. Diese Unterstützung wird automatisch aktiviert, wenn ein JSR-303-Anbieter, z. B. Hibernate Validator, in Ihrem Klassenpfad vorhanden ist. Wenn diese Option aktiviert ist, können Sie die Validierung einfach auslösen, indem Sie einen Controller-Methodenparameter mit der Annotation @Valid versehen: Nach dem Binden eingehender POST-Parameter wird die AppointmentForm validiert. In diesem Fall ist das Überprüfen des Datumsfeldwerts nicht null und tritt in der Zukunft auf.


Weitere Informationen finden Sie hier:
http://blog.springsource.com/2009/11/17/spring-3-type-conversion-and-validation/

mhshams
quelle
36

Wenn Sie die obigen Antworten ergänzen, sehen Sie sich Folgendes an. AppointmentFormDie dateSpalte von ist mit einigen Anmerkungen versehen. Durch eine @ValidAnmerkung, die Validierungen auf dem AppointmentForm(in diesem Fall @NotNullund @Future) auslöst . Diese Anmerkungen können von verschiedenen JSR-303-Anbietern stammen (z. B. Hibernate, Spring usw.).

    @RequestMapping(value = "/appointments", method = RequestMethod.POST)
    public String add(@Valid AppointmentForm form, BindingResult result) {
        ....
    }

    static class AppointmentForm {

        @NotNull @Future
        private Date date;
    }
Charith De Silva
quelle
1
Ich habe einen ähnlichen Code. Ich hatte entfernt @Validauf ApplicationFormParameter aber noch wurde Validierungen beschossen date(Set als null) Feld. Bitte erkläre.
Lupchiazoem
18

IIRC @Valid ist keine Spring-Annotation, sondern eine JSR-303-Annotation (dies ist der Bean-Validierungsstandard). Grundsätzlich wird geprüft, ob die Daten, die Sie an die Methode senden, gültig sind oder nicht (die scriptFile wird für Sie validiert).

Mateusz Dymczyk
quelle
1
Was bedeutet es für "es wird die scriptFile für Sie validieren"? Überprüfen Sie, ob es nicht null ist, eine Syntax oder einen Inhalt hat? Mit anderen Worten, was validiert es und wie? Sollte der Benutzer etwas implementieren? Wo kann ich Informationen dazu bekommen? Vielen Dank!
Neffe vom
17

@Validan sich hat nichts mit Frühling zu tun. Es ist Teil der Bean Validation-Spezifikation (es gibt mehrere davon, die letzte ist JSR 380 ab der zweiten Jahreshälfte 2017), @Validist jedoch sehr alt und leitet sich vollständig von JSR 303 ab.

Wie wir alle wissen, ist Spring sehr gut darin, die Integration in alle verschiedenen JSRs und Java-Bibliotheken im Allgemeinen (denken Sie an JPA, JTA, Caching usw.) bereitzustellen, und natürlich haben sich diese Leute auch um die Validierung gekümmert. Eine der Schlüsselkomponenten, die dies erleichtert, ist MethodValidationPostProcessor .

Der Versuch, Ihre Frage zu beantworten, @Validist sehr praktisch für die sogenannte Validierungskaskadierung, wenn Sie ein komplexes Diagramm und nicht nur Elemente eines Objekts der obersten Ebene validieren möchten. Jedes Mal, wenn Sie tiefer gehen möchten, müssen Sie verwenden @Valid. Das schreibt JSR vor. Spring wird dem mit einigen geringfügigen Abweichungen entsprechen (zum Beispiel habe ich versucht, @Validatedanstelle der @ValidRestController-Methode zu setzen, und die Validierung funktioniert, aber das Gleiche gilt nicht für reguläre "Service" -Beans).

Yuranos
quelle
Aber was validiert?
Neffe vom
Bitte erläutern Sie, @nephewtom. Was möchten Sie klarstellen?
Yuranos
Ich habe JSR 303: Bean Validation, beanvalidation.org/1.0/spec gelesen, aber ich verstehe immer noch nicht, an welcher Validierung durchgeführt wird ScriptFile scriptFile.
Neffe vom
ScriptFile enthält wahrscheinlich eine Reihe von Feldern und diese Felder enthalten auch Anmerkungen. Hier setzt die Validierung an. Basierend auf der ursprünglichen Frage ist nicht klar, was genau in der ScriptFile-Klasse enthalten ist.
Yuranos
OK danke. Könnten Sie ein Beispiel dafür geben, was validiert werden könnte, wenn seine Felder einen String, eine Ganzzahl und eine Bean enthalten?
Neffe vom
2
public String create(@Valid @NotNull ScriptFile scriptFile, BindingResult result, ModelMap modelMap) {    
    if (scriptFile == null) throw new IllegalArgumentException("A scriptFile is required");        

Ich denke, diese @NotNullAnmerkung ist daher gültig, wenn keine Bedingung benötigt wird.

mzlobecki
quelle
1

Nur zur Ergänzung der oben Antwort, in einer Web - Anwendung @validwird verwendet , wenn die Bohne validiert werden soll , wird auch bei der Validierung kommentierten Anmerkungen zum Beispiel @NotNull, @Email(Hibernate Annotations) so , wenn während Eingabe von Benutzer immer die Werte validiert werden kann und verbindliche Ergebnis der Validierung wird Ergebnisse. bindingResult.hasErrors()wird feststellen, ob eine Validierung fehlgeschlagen ist.

Puneet Goyal
quelle
1

Ein weiterer praktischer Aspekt von @Valid, der oben nicht erwähnt wurde, ist, dass @Valid (dh Verwenden von Postman zum Testen eines Endpunkts) die Ausgabe eines falschen REST-Aufrufs in formatierten JSON anstelle eines Blobs aus kaum lesbarem Text formatiert. Dies ist sehr nützlich, wenn Sie eine kommerziell konsumierbare API für Ihre Benutzer erstellen.

Sean Gildea
quelle
0

Ich glaube, ich weiß, wohin Ihre Frage führt. Und da diese Frage in den Suchergebnissen von Google auftaucht, kann ich eine einfache Antwort darauf geben, was die Annotation @Valid bewirkt.

Ich werde 3 Szenarien vorstellen, wie ich @Valid verwendet habe

Modell:

public class Employee{
private String name;
@NotNull(message="cannot be null")
@Size(min=1, message="cannot be blank")
private String lastName;
 //Getters and Setters for both fields.
 //...
}

JSP:

...
<form:form action="processForm" modelAttribute="employee">
 <form:input type="text" path="name"/>
 <br>
 <form:input type="text" path="lastName"/>
<form:errors path="lastName"/>
<input type="submit" value="Submit"/>
</form:form>
...

Controller für Szenario 1:

     @RequestMapping("processForm")
        public String processFormData(@Valid @ModelAttribute("employee") Employee employee){
        return "employee-confirmation-page";
    }

In diesem Szenario wird nach dem Absenden Ihres Formulars mit einem leeren Feld für den Nachnamen eine Fehlerseite angezeigt, da Sie Validierungsregeln anwenden, diese jedoch überhaupt nicht verarbeiten.

Beispiel für diesen Fehler: Ausnahmeseite

Controller für Szenario 2:

 @RequestMapping("processForm")
    public String processFormData(@Valid @ModelAttribute("employee") Employee employee,
BindingResult bindingResult){
                return bindingResult.hasErrors() ? "employee-form" : "employee-confirmation-page";
            }

In diesem Szenario übergeben Sie alle Ergebnisse dieser Validierung an das BindingResult. Es liegt also an Ihnen, zu entscheiden, was mit den Validierungsergebnissen dieses Formulars geschehen soll.

Controller für Szenario 3:

@RequestMapping("processForm")
    public String processFormData(@Valid @ModelAttribute("employee") Employee employee){
                return "employee-confirmation-page";
            }
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Map<String, String> invalidFormProcessor(MethodArgumentNotValidException ex){
  //Your mapping of the errors...etc
}

In diesem Szenario behandeln Sie die Fehler immer noch nicht wie im ersten Szenario, sondern übergeben sie an eine andere Methode, die die Ausnahme berücksichtigt , die @Valid bei der Verarbeitung des Formularmodells auslöst. Überprüfen Sie dies, um zu sehen, was mit dem Mapping und all dem zu tun ist.

Um es zusammenzufassen : @Valid auf seine eigene mit nichts mehr tun , dass Auslöser der Validierung Validierung JSR 303 kommentierten Felder ( @NotNull, @Email, @size, etc ... ), müssen Sie noch eine Strategie bestimmen , was zu tun mit den Ergebnissen dieser Validierung.

Ich hoffe, ich konnte etwas für Leute klären, die darüber stolpern könnten.

Alan Balderas Sánchez
quelle