Ich würde gerne wissen, was der sauberste und beste Weg ist, um eine Formularvalidierung von Benutzereingaben durchzuführen. Ich habe einige Entwickler implementieren sehen org.springframework.validation.Validator
. Eine Frage dazu: Ich habe gesehen, dass es eine Klasse bestätigt. Muss die Klasse manuell mit den Werten aus der Benutzereingabe gefüllt und dann an den Validator übergeben werden?
Ich bin verwirrt über den saubersten und besten Weg, um die Benutzereingaben zu validieren. Ich kenne die traditionelle Methode zur Verwendung request.getParameter()
und anschließenden manuellen Überprüfung nulls
, möchte jedoch nicht die gesamte Validierung in meinem durchführen Controller
. Einige gute Ratschläge in diesem Bereich werden sehr geschätzt. Ich verwende Hibernate in dieser Anwendung nicht.
quelle
Antworten:
Mit Spring MVC gibt es drei verschiedene Möglichkeiten, eine Validierung durchzuführen: manuelle Verwendung von Anmerkungen oder eine Mischung aus beiden. Es gibt keinen eindeutigen "saubersten und besten Weg" zur Validierung, aber es gibt wahrscheinlich einen, der besser zu Ihrem Projekt / Problem / Kontext passt.
Lassen Sie uns einen Benutzer haben:
Methode 1: Wenn Sie Spring 3.x + und eine einfache Validierung durchführen müssen, verwenden Sie
javax.validation.constraints
Anmerkungen (auch als JSR-303-Anmerkungen bezeichnet).Sie benötigen einen JSR-303-Anbieter in Ihren Bibliotheken, z. B. Hibernate Validator, der die Referenzimplementierung darstellt (diese Bibliothek hat nichts mit Datenbanken und relationaler Zuordnung zu tun, sondern führt nur eine Validierung durch :-).
Dann hätten Sie in Ihrem Controller so etwas wie:
Beachten Sie das @Valid: Wenn der Benutzer zufällig einen Nullnamen hat, ist result.hasErrors () wahr.
Methode 2: Wenn Sie über eine komplexe Validierung verfügen (z. B. Validierungslogik für große Unternehmen, bedingte Validierung über mehrere Felder usw.) oder aus irgendeinem Grund Methode 1 nicht verwenden können, verwenden Sie die manuelle Validierung. Es wird empfohlen, den Code des Controllers von der Validierungslogik zu trennen. Erstellen Sie Ihre Validierungsklasse (n) nicht von Grund auf neu, Spring bietet eine praktische
org.springframework.validation.Validator
Oberfläche (seit Spring 2).Nehmen wir an, Sie haben
und Sie möchten eine "komplexe" Validierung durchführen, z. B.: Wenn das Alter des Benutzers unter 18 Jahren liegt, darf der verantwortliche Benutzer nicht null und das Alter des verantwortlichen Benutzers über 21 Jahre sein.
Sie werden so etwas tun
Dann hätten Sie in Ihrem Controller:
Wenn Validierungsfehler vorliegen, ist result.hasErrors () wahr.
Hinweis: Sie können den Validator auch in einer @ InstBinder-Methode des Controllers mit "binder.setValidator (...)" festlegen (in diesem Fall wäre eine gemischte Verwendung der Methoden 1 und 2 nicht möglich, da Sie die Standardeinstellung ersetzen Validator). Oder Sie können es im Standardkonstruktor des Controllers instanziieren. Oder haben Sie einen @ Component / @ Service UserValidator, den Sie in Ihren Controller einfügen (@Autowired): sehr nützlich, da die meisten Validatoren Singletons sind + das Verspotten von Unit-Tests einfacher wird + Ihr Validator andere Spring-Komponenten aufrufen könnte.
Methode 3: Warum nicht eine Kombination beider Methoden verwenden? Überprüfen Sie die einfachen Dinge wie das Attribut "name" mit Anmerkungen (schnell, präzise und besser lesbar). Behalten Sie die umfangreichen Validierungen für Validatoren bei (wenn es Stunden dauern würde, benutzerdefinierte komplexe Validierungsanmerkungen zu codieren, oder wenn es nicht möglich ist, Anmerkungen zu verwenden). Ich habe das bei einem früheren Projekt gemacht, es hat wie ein Zauber funktioniert, schnell und einfach.
Achtung: Sie müssen Fehler Validierung Handhabung für die Ausnahmebehandlung . Lesen Sie diesen Beitrag, um zu erfahren, wann Sie sie verwenden müssen.
Verweise :
quelle
Es gibt zwei Möglichkeiten, Benutzereingaben zu validieren: Anmerkungen und das Erben der Validator-Klasse von Spring. Für einfache Fälle sind die Anmerkungen nett. Wenn Sie komplexe Validierungen benötigen (z. B. eine feldübergreifende Validierung, z. B. das Feld "E-Mail-Adresse überprüfen") oder wenn Ihr Modell an mehreren Stellen in Ihrer Anwendung mit unterschiedlichen Regeln validiert wird oder wenn Sie nicht in der Lage sind, Ihre zu ändern Modellieren Sie das Objekt, indem Sie Anmerkungen darauf platzieren. Der vererbungsbasierte Validator von Spring ist der richtige Weg. Ich werde Beispiele von beiden zeigen.
Der eigentliche Validierungsteil ist derselbe, unabhängig davon, welche Art von Validierung Sie verwenden:
Wenn Sie Anmerkungen verwenden,
Foo
sieht Ihre Klasse möglicherweise folgendermaßen aus:Anmerkungen oben sind
javax.validation.constraints
Anmerkungen. Sie können auch den Ruhezustand verwendenorg.hibernate.validator.constraints
, aber es sieht nicht so aus, als würden Sie den Ruhezustand verwenden.Wenn Sie alternativ Spring's Validator implementieren, erstellen Sie alternativ eine Klasse wie folgt:
Wenn Sie den obigen Validator verwenden, müssen Sie den Validator auch an den Spring-Controller binden (nicht erforderlich, wenn Sie Anmerkungen verwenden):
Siehe auch Spring-Dokumente .
Hoffentlich hilft das.
quelle
Foo
Parameter in der Handler-Methode. Könntest Du das erläutern?Ich möchte die nette Antwort von Jerome Dalbert erweitern. Ich fand es sehr einfach, eigene Anmerkungsprüfer auf JSR-303-Weise zu schreiben. Sie sind nicht auf die Validierung "eines Felds" beschränkt. Sie können Ihre eigene Anmerkung auf Textebene erstellen und eine komplexe Validierung durchführen (siehe Beispiele unten). Ich bevorzuge diesen Weg, weil ich nicht verschiedene Arten der Validierung (Spring und JSR-303) mischen muss, wie es Jerome tut. Auch diese Validatoren sind "Spring-fähig", sodass Sie @ Inject / @ Autowire sofort verwenden können.
Beispiel für die Validierung benutzerdefinierter Objekte:
Beispiel für die Gleichheit generischer Felder:
quelle
ElementType.METHOD
in@Target
.Wenn Sie dieselbe Fehlerbehandlungslogik für verschiedene Methodenhandler haben, erhalten Sie viele Handler mit folgendem Codemuster:
Angenommen, Sie erstellen RESTful-Services und möchten
400 Bad Request
für jeden Validierungsfehlerfall zusammen mit Fehlermeldungen zurückkehren . Dann wäre der Fehlerbehandlungsteil für jeden einzelnen REST-Endpunkt, der validiert werden muss, gleich. Die gleiche Logik in jedem einzelnen Handler zu wiederholen, ist nicht so trocken !Eine Möglichkeit, dieses Problem zu lösen, besteht darin, die unmittelbar
BindingResult
nach jeder zu validierenden Bean zu löschen . Nun würde Ihr Handler so aussehen:Auf diese Weise
MethodArgumentNotValidException
wird a von Spring geworfen , wenn die gebundene Bohne nicht gültig war . Sie können eine definierenControllerAdvice
, die diese Ausnahme mit derselben Fehlerbehandlungslogik behandelt:Sie können den Basiswert weiterhin
BindingResult
mit dergetBindingResult
Methode von untersuchenMethodArgumentNotValidException
.quelle
Hier finden Sie ein vollständiges Beispiel für die Spring Mvc-Validierung
quelle
Fügen Sie diese Bean in Ihre Konfigurationsklasse ein.
und dann können Sie verwenden
zum manuellen Validieren einer Bean. Dann erhalten Sie alle Ergebnisse in BindingResult und können von dort abrufen.
quelle