1. Parameterüberprüfung
In der Entwicklung müssen Sie häufig einen Code für die Feldüberprüfung schreiben, wie z.
Der Hibernate Validator (offizielles Dokument) bietet eine relativ vollständige und bequeme Überprüfungsmethode.
Das Spring-Boot-Starter-Web-Paket enthält das Hibernate-Validator-Paket, und es müssen nicht auf die Abhängigkeit von Hibernate Validator verweisen.
2. Hibernate Validator -Überprüfung Demo
Schauen wir uns zunächst eine einfache Demo an und fügen Sie die Annotation des Validators hinzu:
import org.hibernate.validator.constraints.notblank; import javax.validation.constraints.assertfalse; import Javax.Validation.Constraints.Pattern;
@Getter@setzter@noargSconstructorPublic -Klasse Demomodel {@notblank (Message = "Benutzername kann nicht leer sein") privater String -Benutzername; @Notblank (Message = "Alter kann nicht leer sein") @Pattern (regexp = "^[0-9] {1,2} $", Message = "Alter falsch") private String-Alter; @AssertFalse (Message = "Muss falsch sein") Private boolean isFalse; / *** Wenn es leer ist, wird es nicht überprüft, und wenn es nicht leer ist, wird es überprüft.BindingResult ist eine Sammlung von Ergebnissen, die die Überprüfung nicht übergeben: BindingResult:
@RequestMapping ("/Demo2") public void Demo2 (@RequestBody @valid Demomodel Demo, BindingResult Ergebnis) {if (result.hasErrors ()) {für (objecterror error: result.getAllErrors ()) {system.out.println (error.GetDefault. }}} Parameter, die durch Postanfrage übergeben wurden :{"userName":"dd","age":120,"isFalse":true,"birthday":"21010-21-12"}
Ausgangsergebnis:
Das Geburtsdatum ist falsch und muss falsch sein
Falsches Alter
Die Parameterüberprüfung ist sehr bequem. Wenn die Annotation + Überprüfung auf dem Feld nicht übergeben wird, kann sie die Handschrift vieler nicht leerer und Feldbeschränkungscodes ersetzen. Im Folgenden haben wir ein tieferes Verständnis dafür, wie die Parameterüberprüfung abspielt.
3. Hibernate -Überprüfungsmodus
Sorgfältige Leser müssen festgestellt haben, dass im obigen Beispiel alle Sätze, die nicht überprüft werden, gleichzeitig zurückgegeben werden. Wenn das erste Feld nicht den Bestätigungsanforderungen erfüllt, kann die Anfrage direkt abgelehnt werden. Der Hibernate Validator hat die folgenden zwei Überprüfungsmodi:
1. Normaler Modus (dieser Modus ist standardmäßig)
Normaler Modus (alle Attribute werden überprüft und dann werden alle Überprüfungsfehlerinformationen zurückgegeben)
2. schnelles Versagen, in den Modus zurückzukehren
Schneller Rückgabemodus (zurückkehren, solange ein Verifizierungsfehler vorliegt)
Zwei Konfigurationsmethoden der Verifizierungsmodus: (Siehe offizielle Dokumentation)
failfast: True Fast Fail Return -Modus Falschem Normalmodus
ValidatorFactory validatorFactory = validation.byProvider (hibernatevalidator.class) .configure () .Failfast (true) .buildvalidatorFactory (); Validator validator = validatorFactory.getValidator ();
und (hibernate.validator.fail_fast: True Fast Fail Return -Modus Falschem Normalmodus)
ValidatorFactory validatorFactory = validation.byProvider (hibernatevalidator.class) .configure () .addProperty ("hibernate.validator.fail_fast", "true") .buildvalidatorFactory (); Validator validator = validatorFactory.getValidator ();4. Zwei Arten von Überprüfungen von Winterschlafat
Konfigurieren Sie den Hibernate -Validator, um den Modus zum schnellen Fehler zurückzugeben:
@ConfigurationPublic Class ValidatorConfiguration {@Bean Public Validator Validator () {validatorFactory validatorFactory = validation.ByRovider (hibernatevalidator.class) .configure () .Addproperty ("hibernate.validator.fail_fast", "wahr". Validator validator = validatorFactory.getValidator (); Return Validator; }}1. Überprüfung der Parameterüberprüfung
Fügen Sie wie im Beispiel in der Demo bei der Überprüfung der Anforderungsparameter @Valid zwischen der Demomodell -Demo @RequestBody hinzu und fügen Sie dann Bindindresult hinzu. Für mehrere Parameter können Sie mehrere @Valid und BindingResult hinzufügen, z. B.:
public void test () ( @RequestBody @valid Demomodel Demo, BindingResult -Ergebnis) Public void test () ( @RequestBody @valid Demomodel Demo, BindingResult -Ergebnis, @RequestBody @Valid Demomodel Demo2, BindingResult -Ergebnis2)
@RequestMapping ("/Demo2") public void Demo2 (@RequestBody @valid Demomodel Demo, BindingResult Ergebnis) {if (result.hasErrors ()) {für (objecterror error: result.getAllErrors ()) {system.out.println (error.GetDefault. }}}2. Parameterüberprüfung abrufen (@RequestParam Parameterüberprüfung)
Mit der Methode zum Überprüfen von Bohnen gibt es keine Möglichkeit, den Inhalt von RequestParam zu überprüfen. Im Allgemeinen wird bei der Verarbeitung von GET -Anforderungen (oder weniger Parametern) der folgende Code verwendet:
@RequestMapping (value = "/Demo3", method = requestMethod.get) public void Demo3 (@RequestParam (name = "grade", fordert = true) int grade,@requestparam (name = "klassenzimmer", fordert = true) int classroom) {System.out.println (Klasse + "," + Classroom); }Die Verwendung der @Valid -Annotation, um die Parameter, die dem RequestParam entsprechen, zu kommentieren, ist ungültig. Die @Validated Annotation ist erforderlich, um die Überprüfung wirksam zu werden. Wie unten gezeigt:
A. Zu diesem Zeitpunkt müssen Sie die Bohne von MethodValidationPostProcessor verwenden:
@Bean public methodValidationPostProcessor methodValidationPostProcessor () { / ** Standard ist der normale Modus, und alle Überprüfungen werden zurückgegeben, ohne die Informationssammlung zu übergeben* / Neue MethodValidationPostProcessor (); } Oder Sie können den Validator für MethodValidationPostProcessor festlegen (da der Validator derzeit nicht zur Überprüfung verwendet wird, funktioniert die Validator -Konfiguration nicht).
@Bean public methodValidationPostProcessor methodValidationPostProcessor () {methodValidationPostPostProcessor postprozessor = new methodValidationPostProcessor (); / ** Validator -Modus auf schnelle Fehler zurückgeben*/ postprozessor.setValidator (validator ()); Postprozessor zurückgeben; } @Bean public validator validator () {validatorFactory validatorFactory = validation.byProvider (hibernatevalidator.class) .configure () .Addproperty ("hibernate.validator.fail_fast", "true") .buildvalidatorFactory (); Validator validator = validatorFactory.getValidator (); Return Validator; }B. Fügen Sie dem Controller Annotation hinzu, wo sich die Methode @Validated befindet
@RequestMapping (" /validation")@rastController@ValidatedPublic Class ValidationController { /** Wenn es nur wenige Objekte gibt, schreiben Sie einfach die Parameter in die Controller -Ebene und verifizieren Sie sie dann in der Controller -Ebene. */ @RequestMapping (value = "/ Demo3", method = requestMethod.get) public void Demo3 (@Range (min = 1, max = 9, Message = "kann nur von 1-9") @RequestParam (name = "grade", fordert = true) in int @Min (Value = 1, Messing = "-Klassel-Message =" Message = "Messing =" Messing = "Messing =") sein. sein 99 ") @RequestParam (name =" klassenzimmer ", erforderlich = true) int klassenzimmer) {System.out.println (grade +", " + klassenzimmer); }}C. Kehren Sie zur Eingabeaufforderung zur Überprüfungsinformationen zurück
Sie können sehen: Wenn die Überprüfung fehlschlägt, wird eine Ausnahme von ConstraintViolationException ausgelöst und die gleiche Hangausnahme wird behandelt:
@ControllerAdvice @componentpublic class globalExceptionHandler {@ExceptionHandler @ResponseBody @responSestatus (httpstatus.bad_request) public String Handle (validationException Exception) {if (ExceptionsinstanceOf ConstraintviolationException) {ConstraintviolationException EXS = (ConstraintviolationExation) Ausnahme; Set <ConstraintViolation <? >> Verstöße = exs.getConstraintViolations (); für (ConstraintViolation <?> Artikel: Verstöße) { / ** Drucken Sie die Informationen, die die Bestätigung nicht übergeben können* / system.out.println (item.getMessage ()); }} return "schlechte Anfrage,"; }}D. Überprüfung
Browser -Serviceanforderung Adresse: http: // localhost: 8080/validation/deMo3? Grade = 18 & klassenzimmer = 888
Die Ausgabeinformationen, wenn der MethodValidationPostProcessor zurückgegeben hat, ohne den schnellen Fehler zu konfigurieren, lautet wie folgt:
Noten können nur von 1-9 stammen
Die maximale Klasse kann nur 99 sein
Wenn der MethodValidationPostProcessor mit der Rückgabe der schnellen Fehler konfiguriert ist, lautet die Ausgabeinformationen wie folgt:
Noten können nur von 1-9 stammen
Browser -Serviceanforderung Adresse: http: // localhost: 8080/validation/deMo3? Grade = 0 & classroom = 0
Die Ausgabeinformationen, wenn der MethodValidationPostProcessor zurückgegeben hat, ohne den schnellen Fehler zu konfigurieren, lautet wie folgt:
Noten können nur von 1-9 stammen
Die Mindestklasse kann nur 1 sein
Wenn der MethodValidationPostProcessor mit der Rückgabe der schnellen Fehler konfiguriert ist, lautet die Ausgabeinformationen wie folgt:
Noten können nur von 1-9 stammen
3. Modellüberprüfung
Modell zu verifizieren:
@Datapublic Class Demo2 {@length (min = 5, max = 17, Message = "Länge zwischen [5,17]") private String -Länge; / ** @Größe kann Integer nicht überprüfen, geeignet für Zeichenfolge, Sammlung, Karte und Arrays*/ @size (min = 1, max = 3, Message = "Größe zwischen [1,3]") Private String Age; @Range (min = 150, max = 250, Message = "Bereich ist zwischen [150.250]") Private int hoch; @Size (min = 3, max = 5, message = "Die Größe der Liste ist in [3,5]") private Liste <string> liste;}Überprüfen Sie das Modell, alle folgenden Überprüfungen werden übergeben:
@Autowired Private Validator Validator; @RequestMapping ("/Demo3") public void Demo3 () {Demo2 Demo2 = new Demo2 (); Demo2.Setage ("111"); Demo2.Sthigh (150); Demo2.SetLength ("abcde"); Demo2.setList (New ArrayList <String> () {{add ("111"); add ("222"); add ("333");}}); Set <ConstraintViolation <Demo2 >> Verstöße = validator.Validate (Demo2); für (ConstraintViolation <Deo2> Modell: Verstöße) {System.out.println (model.getMessage ()); }}4. Objektkaskadenüberprüfung
Das Objekt enthält ein anderes Objekt als Eigenschaft und füge @Valid in die Eigenschaft hinzu, um die Überprüfung innerhalb des Objekts als Eigenschaft zu überprüfen: (Beim Überprüfen des Demo2 -Beispiels können Sie die Felder von Demo2 überprüfen)
@Datapublic Class Demo2 {@size (min = 3, max = 5, Message = "Die Größe der Liste ist in [3,5]") private Liste <string> Liste; @Notnull @valid private Demo3 Demo3;} @DataPublic Class Demo3 {@Length (min = 5, max = 17, Message = "Längenlänge ist zwischen [5,17]") private String extfield;}Kaskadenüberprüfung:
/ ** Bean ist mit einem schnellen Fehler zurückgegeben. @RequestMapping ("/Demo3") public void Demo3 () {Demo2 Demo2 = new Demo2 (); Demo2.setList (New ArrayList <String> () {{add ("111"); add ("222"); add ("333");}}); Demo3 Demo3 = New Demo3 (); Demo3.Setextfield ("22"); Demo2.SetDemo3 (Demo3); Set <ConstraintViolation <Demo2 >> Verstöße = validator.Validate (Demo2); für (ConstraintViolation <Deo2> Modell: Verstöße) {System.out.println (model.getMessage ()); }}Das Extfield -Feld von Demo3 kann überprüft werden.
5. Gruppenüberprüfung
Schlussfolgerung: Überprüfen Sie bei der Überprüfung der Gruppierungssequenz sie in der angegebenen Gruppierungsreihenfolge. Wenn die vorherige Überprüfung fehlschlägt, kann die anschließende Gruppierung nicht überprüft werden.
Es gibt ein Szenario, in dem bei hinzugefügtem Hinzufügen neuer Benutzerinformationen keine BenutzerID überprüft werden muss (da das System generiert wird). Bei der Änderung muss die BenutzerID die BenutzerID überprüfen und die Gruppenüberprüfungsfunktion des Benutzers zum Validator kann verwendet werden.
Setzen Sie den Validator auf den normalen Verifizierungsmodus ("Hibernate.validator.fail_fast", "False") und verwenden Sie die Verifizierungsgruppe, GroupB und das Modell:
Groupa, GroupB: Public Interface Groupa {} public interface GroupB {}Modell überprüfen: Person
@Datapublic Class Person {@notblank @Range (min = 1, max = integer.max_value, message = "Muss größer als 0 sein", gruppen = {gruppe.class}) / ** Benutzer -ID* / private Integer userId; @Notblank @Length (min = 4, max = 20, message = "Muss in [4,20]", gruppen = {GroupB.Class}) / ** Benutzername* / private String -Benutzername; @Notblank @Range (min = 0, max = 100, Message = "Alter muss bei [0,100]", gruppen = {default.class}) / ** age* / privat Integer Age; @Range (min = 0, max = 2, Message = "Geschlecht muss bei [0,2]", gruppen = {GroupB.Class}) /** Gender 0: unbekannt; 1: männlich; 2: weiblich*/ privates Ganzzahl Sex;}Wie oben persönlich gezeigt, werden die drei Gruppen jeweils wie folgt validiert:
A. Gruppierung
Es werden nur Gruppierungen von Groupa und GroupB -Tags verifiziert:
@RequestMapping ("/Demo5") public void Demo5 () {Person p = new Person (); / ** Groupa-Überprüfung ist nicht bestanden*/ P.SetUserid (-12); /** Groupa -Verifizierungspass*///p.setUserid(12); P.Setusername ("a"); P.Setage (110); P.SetSex (5); Set <ConstraintViolation <Person >> validate = validator.validate (P, Groupa.Class, GroupB.Class); für (ConstraintViolation <Person> Element: validate) {System.out.println (item); }}oder
@RequestMapping ("/Demo6") public void Demo6 (@validated ({Groupa.class, GroupB.Class}) Person P, BindingResult -Ergebnis) {if (result.hasErrors ()) {list <objecterror> Allerrors = result.getallrors (); für (objecterror error: Alerrors) {System.out.println (Fehler); }}}Wenn Groupa, GroupB und Standard nicht validiert werden:
Die Überprüfungsinformationen sind wie folgt:
ConstraintViolationImpl {interpolatedMessage = 'muss in [4,20]', PropertyPath = Benutzername, RootBeanClass = Class Validator.demo.Project.model.person, MessenAGetemplate = 'MUSS IN [4,20]'} ConstraintImpl {interpolatedMessage = 'must sein, userid, {messinagetemplate =' must sein,} useriDpl. validator.demo.project.model.person, MessAgetemplate = 'muss größer als 0'} ConstraintViolationImpl {interpolatedMessage = 'Geschlecht sein muss in [0,2]', PropertyPath = Sex, RootbeanClass = Klasse Validator.demo.Project.Model.Person, Messagetemplass = Messagetempla, Messagetempla, 'Messagetempla, Messagetempla,' Messagetemplate = Messagetempla, 'Messagetemplate = MessagetemPl.'Wenn die Gruppenüberprüfung bestanden wird, wird GroupB und Standardbestätigung nicht bestanden:
Die Überprüfungsinformationen sind wie folgt:
ConstraintViolationImpl {interpolatedMessage = 'muss in [4,20]', PropertyPath = Benutzername, RootbeanClass = Klasse Validator.demo.Project.model.person, MessAgetemplate = 'Muss in [4,20]'} ConstraintImpl {interpolated Sage = 'must sein, in [0,2], sexuelle sexuelle, sexuelle. rootbeanclass = class validator.demo.project.model.person, MessAgetemplate = 'Geschlecht muss in [0,2]'} seinB. Gruppensequenz
Sie können nicht nur angeben, ob Sie nach Gruppen überprüfen sollen, sondern auch die Überprüfungsreihenfolge der Gruppe angeben. Wenn die Überprüfung der vorherigen Gruppe fehlschlägt, wird die Überprüfung der nächsten Gruppe nicht durchgeführt:
Sequenz der angegebenen Gruppe (Groupa》 GroupB》 Standard):
@Groupsequence ({Groupa.Class, GroupB.Class, default.class}) public interface Grouporder {}Testdemo:
@RequestMapping ("/Demo7") public void Demo7 () {Person p = new Person (); /** Groupa-Überprüfung ist nicht bestanden*//p.setUserid(-12); / ** Groupa -Verifizierungspass*/ P.Setuserid (12); P.Setusername ("a"); P.Setage (110); P.SetSex (5); Set <ConstraintViolation <Person >> validate = validator.validate (p, GroupOrder.class); für (ConstraintViolation <Person> Element: validate) {System.out.println (item); }}oder
@RequestMapping ("/Demo8") public void Demo8 (@validated ({GroupOrder.class}) Person P, BindingResult -Ergebnis) {if (result.hasErrors ()) {list <objecterror> Alerrors = result.getAllErrors (); für (objecterror error: Alerrors) {System.out.println (Fehler); }}}Wenn Groupa, GroupB und Standard nicht validiert werden:
Die Überprüfungsinformationen sind wie folgt:
ConstraintViolationImpl {interpolatedMessage = 'Muss größer als 0' sein, PropertyPath = UserId, RootBeanClass = Class Validator.demo.project.model.person, MessAgetemplate = Muss größer als 0 '} seinWenn die Gruppenüberprüfung bestanden wird, wird GroupB und Standardbestätigung nicht bestanden:
Die Überprüfungsinformationen sind wie folgt:
ConstraintViolationImpl {interpolatedMessage = 'muss in [4,20]', PropertyPath = Benutzername, RootbeanClass = Klasse Validator.demo.Project.model.person, MessAgetemplate = 'Muss in [4,20]'} ConstraintImpl {interpolated Sage = 'must sein, in [0,2], sexuelle sexuelle, sexuelle. rootbeanclass = class validator.demo.project.model.person, MessAgetemplate = 'Geschlecht muss in [0,2]'} seinSchlussfolgerung: Überprüfen Sie bei der Überprüfung der Gruppierungssequenz sie in der angegebenen Gruppierungsreihenfolge. Wenn die vorherige Überprüfung fehlschlägt, kann die anschließende Gruppierung nicht überprüft werden.
5. Sonderanfertiger
Im Allgemeinen kann eine benutzerdefinierte Überprüfung viele Probleme lösen. Es gibt aber auch Zeiten, in denen die Situation nicht erfüllt werden kann. Zu diesem Zeitpunkt können wir die Validator -Schnittstelle implementieren und den von uns benötigten Validator anpassen.
Wie nachstehend gezeigt, wird ein benutzerdefinierter Fallvalidator implementiert:
public enum casemode {obere, untere;}@target ({elementtype.method, elementtype.field, elementtype.Annotation_type})@retention (retentionPolicy.runtime) @Constraint (validatedBy = checkCasevalidator.classe) @DocumentedPublic @InterfactCock {String -Message () -Anly "; Klasse <?> [] Gruppen () Standard {}; Klasse <? erweitert Payload> [] payload () Standard {}; Casemode value ();} öffentliche Klasse CheckCaseValidator implementiert ConstraintValidator <CheckCase, String> {private Casemode Casemode; public void initialize (checkCase checkCase) {this.caSemode = checkCase.Value (); } public boolean isvalid (String S, ConstraintValidatorContext ConstraintValidatorContext) {if (s == null) {return true; } if (casemode == casemode.upper) {return s.equals (s.touppercase ()); } else {return s.equals (S.TolowerCase ()); }}}Modell zur Überprüfung:
öffentliche Klasse Demo {@checkcase (value = casemode.lower, Message = "Benutzername muss Kleinbuchstaben sein") privater String -Benutzername; public String getUnername () {return userername; } public void setUnername (String -Benutzername) {this.username = userername; }}Validator -Konfiguration:
@Bean Public Validator Validator () {validatorFactory validatorFactory = validation.ByProvider (hibernatevalidator.class) .configure () .Addproperty ("hibernate.validator.fail_fast", "true") .buildvalidatorfactory (); Validator validator = validatorFactory.getValidator (); Return Validator; }Überprüfungstest:
@RequestMapping ("/Demo4") public void Demo4 () {Demo Demo = New Demo (); Demo.Setusername ("Benutzername"); Set <ConstraintViolation <Demo >> validate = validator.Validate (Demo); für (ConstraintViolation <Dec.> Dem: validate) {System.out.println (Dem.getMessage ()); }}Ausgangsergebnis:
Benutzername muss Kleinbuchstaben sein
6. Gemeinsame Anmerkungen
Die integrierte Einschränkung in der Bean-Validierung @Null Das kommentierte Element muss null sein @notnull Das kommentierte Element darf nicht null sein. Gleich dem angegebenen Maximalwert @decimalmin (Wert) Das kommentierte Element muss eine Zahl sein, sein Wert muss größer oder gleich dem angegebenen Minimalwert @decimalmax (Wert) Das annotierte Element muss eine Zahl sein, sein Wert muss weniger als oder gleich dem angegebenen Maximumwert @Size @Size @Size (max =, min =) Das annotierte Element, das die Größe der Größe des annotierten Elements, das annotierte Element, das annotierte Element, das annotte Element, das annotte Element, das annotte Element, das annotte Element, das annotte Element sein muss, muss die Größe des annotierten Elements, das die Größe der Größe des annotierten Elements sein muss. Annotierter Element muss eine Zahl sein und ihr Wert muss innerhalb des akzeptablen Bereichs @past sein. Das kommentierte Element muss ein früheres Datum sein. @Length (min =, max =) Die annotierte Zeichenfolge muss innerhalb des angegebenen Bereichs liegen @NotEmpty Die kommentierte Zeichenfolge muss nicht leer sein @Range (min =, max =, message =) Das annotierte Element muss innerhalb des entsprechenden Bereichs sein ///. 0.01@Notnull@decimalmin (value = "0,01", einschließlich = true) private BigDecimal Greatorequalthan; @Length (min = 1, max = 20, Message = "Nachricht kann nicht leer sein") // Länge kann keine Länge verwenden //@Range (min = 1, max = 20, Message = "Message").
7. Referenzmaterialien
Referenzen:
http://docs.jboss.org/hibernate/validator/4.2/reference/zh-cn/html_single/#validator-gettingstarted