Tavaszi MVC egyedi érvényesítés

1. Áttekintés

Általában, amikor a felhasználói bevitelt ellenőriznünk kell, a Spring MVC szabványos előre definiált validátorokat kínál.

Ha azonban egy adott típusú bemenetet ellenőriznünk kell, lehetőségünk van saját, egyedi érvényesítési logikánk létrehozására.

Ebben a cikkben csak ezt fogjuk megtenni - létrehozunk egy egyéni ellenőrzőt az űrlap telefonszámmezővel történő hitelesítéséhez, majd egyéni mezőt mutatunk meg több mező számára.

Ez a cikk a Spring MVC-re összpontosít. Az Érvényesítés a tavaszi rendszerindításban című cikkünk leírja, hogyan kell elvégezni az egyéni érvényesítéseket a tavaszi indításkor.

2. Beállítás

Az API előnyeinek kihasználása érdekében adja hozzá a függőséget a pom.xml fájl:

 org.hibernate hibernate-validator 6.0.10.Final 

A függőség legfrissebb verziója itt ellenőrizhető.

Ha a Spring Boot programot használjuk, akkor csak a spring-boot-starter-web, ami behozza a hibernate-validator függőség is.

3. Egyedi érvényesítés

Egyéni validátor létrehozása azt vonja maga után, hogy saját annotációt készítünk, és a modellünkben felhasználjuk az érvényesítési szabályok érvényesítésére.

Tehát hozzuk létre a sajátunkat egyedi validátor - amely ellenőrzi a telefonszámokat. A telefonszámnak nyolcnál több, de legfeljebb 11 jegyűnek kell lennie.

4. Az új kommentár

Hozzunk létre egy újat @felület megjegyzésünk meghatározásához:

@Documented @Constraint (validatedBy = ContactNumberValidator.class) @Target ({ElementType.METHOD, ElementType.FIELD}) @Retention (RetentionPolicy.RUNTIME) public @interface ContactNumberConstraint {String message () alapértelmezett "Érvénytelen telefonszám"; Osztály [] csoportok () alapértelmezett {}; Class [] hasznos teher () alapértelmezett {}; }

A ... val @Kényszer annotációval definiáltuk azt az osztályt, amely a mezőnket érvényesíteni fogja, a üzenet() a hibaüzenet jelenik meg a felhasználói felületen, és a kiegészítő kód a legtöbb kazánlapkód, amely megfelel a tavaszi szabványoknak.

5. Validátor létrehozása

Hozzunk létre most egy érvényesítő osztályt, amely betartatja az érvényesítés szabályait:

public class ContactNumberValidator végrehajtja a ConstraintValidator {@Override public void inicializálás (ContactNumberConstraint contactNumber) {} @Orride public logikai isValid (String contactField, ConstraintValidatorContext cxt) {return contactField! = null && contactField.matches ("[0-9 (contactField.length ()> 8) && (contactField.length () <14); }}

Az érvényesítési osztály a ConstraintValidator interfészt, és be kell vezetnie a érvényes módszer; ebben a módszerben határoztuk meg az érvényesítési szabályainkat.

Természetesen itt egy egyszerű érvényesítési szabályt alkalmazunk, hogy bemutassuk a validátor működését.

ConstraintValidator dmeghatározza a logikát, hogy érvényesítse az adott objektum adott korlátozását. A megvalósításoknak meg kell felelniük a következő korlátozásnak:

  • az objektumnak nem paraméterezett típussá kell válnia
  • Az objektum általános paramétereinek korlátlan helyettesítő karaktertípusoknak kell lenniük

6. Validációs jelölés alkalmazása

Esetünkben létrehoztunk egy egyszerű osztályt egy mezővel az érvényesítési szabályok alkalmazásához. Itt állítjuk be a kommentált mezőt, amelyet ellenőrizni kell:

@ContactNumberConstraint privát karakterlánc telefon;

Meghatároztunk egy karakterlánc mezőt, és az egyedi jegyzetünkkel annotáltuk @ContactNumberConstraint. Vezérlőnkben hoztuk létre a leképezéseket és kezeltük a hibát, ha van ilyen:

@Controller public class ValidatedPhoneController {@GetMapping ("/ validatePhone") public String loadFormPage (m modell) {m.addAttribute ("validatedPhone", új ValidatedPhone ()); return "telefonHome"; } @PostMapping ("/ addValidatePhone") public String submitForm (@Valid ValidatedPhone validatedPhone, BindingResult result, m Model) {if (result.hasErrors ()) {return "phoneHome"; } m.addAttribute ("message", "Sikeresen mentett telefon:" + validatedPhone.toString ()); return "telefonHome"; }}

Meghatároztuk ezt az egyszerű vezérlőt, amelynek egyetlen van JSP oldalt, és használja a submitForm módszer a telefonszámunk érvényesítésének kikényszerítésére.

7. A nézet

A nézetünk egy alapvető JSP oldal, egyetlen mezővel rendelkező űrlappal. Amikor a felhasználó elküldi az űrlapot, akkor a mezőt érvényesíti az egyéni érvényesítőnk, és átirányítja ugyanarra az oldalra a sikeres vagy sikertelen ellenőrzés üzenetével:

 Telefon: 

8. Vizsgálatok

Most teszteljük a vezérlőnket, és ellenőrizzük, hogy ez megfelelő választ és nézetet ad-e nekünk:

@Test public void givenPhonePageUri_whenMockMvc_thenReturnsPhonePage () {this.mockMvc. perform (get ("/ validatePhone")). andExpect (view (). name ("phoneHome")); }

Teszteljük továbbá, hogy a mezőnk érvényes-e, a felhasználói adatok alapján:

@Test public void givenPhoneURIWithPostAndFormData_whenMockMVC_thenVerifyErrorResponse () {this.mockMvc.perform (MockMvcRequestBuilders.post ("/ addValidatePhone"). Accept (MediaType.TEXT_HTML). Param ("phoneInput). andExpect (model (). attributeHasFieldErrorCode ("validatedPhone", "phone", "ContactNumberConstraint"). ésVárj (nézet (). név ("telefonHome")). andExpect (status (). isOk ()). andDo (print ()); }

A teszt során a felhasználónak megadjuk a "123" értéket, és - amire számítottunk - minden működik és látjuk a hibát az ügyfél oldalon.

9. Egyéni osztályszintű érvényesítés

Egyéni validációs kommentár osztályban is meghatározható az osztály egynél több attribútumának érvényesítéséhez.

Ennek a forgatókönyvnek egy általános használati esete annak ellenőrzése, hogy egy osztály két mezőjének vannak-e megfelelő értékei.

9.1. A kommentár létrehozása

Tegyünk hozzá egy új feliratot FieldsValueMatch hogy később alkalmazható egy osztályra. Az annotációnak két paramétere lesz terület és fieldMatch amelyek az összehasonlítandó mezők nevét képviselik:

@Constraint (validatedBy = FieldsValueMatchValidator.class) @Target ({ElementType.TYPE}) @Retention (RetentionPolicy.RUNTIME) public @interface FieldsValueMatch {String message () alapértelmezett "A mezők értéke nem egyezik!"; Karaktermező (); String fieldMatch (); @Target ({ElementType.TYPE}) @Retention (RetentionPolicy.RUNTIME) @interface List {FieldsValueMatch [] érték (); }}

Láthatjuk, hogy egyedi kommentárunk tartalmaz egy Lista alinterfész többszörös meghatározásához FieldsValueMatch jegyzetek egy osztályhoz.

9.2. A Validator létrehozása

Ezután hozzá kell adnunk a FieldsValueMatchValidator osztály, amely tartalmazza a tényleges érvényesítési logikát:

public class FieldsValueMatchValidator implementálja a ConstraintValidator {private String mezőt; privát String fieldMatch; public void inicializálás (FieldsValueMatch constraintAnnotation) {this.field = constraintAnnotation.field (); this.fieldMatch = kényszerAnnotation.fieldMatch (); } public logikai isValid (Object value, ConstraintValidatorContext context) {Object fieldValue = new BeanWrapperImpl (value) .getPropertyValue (field); Object fieldMatchValue = new BeanWrapperImpl (érték) .getPropertyValue (fieldMatch); if (fieldValue! = null) {return fieldValue.equals (fieldMatchValue); } else {return fieldMatchValue == null; }}}

A érvényes() metódus beolvassa a két mező értékét, és ellenőrzi, hogy egyenlőek-e.

9.3. A kommentár alkalmazása

Hozzunk létre egy NewUserForm a felhasználói regisztrációhoz szükséges adatokra szánt modellosztály, amely kettővel rendelkezik email és Jelszó attribútumok, kettővel együtt E-mail megerősítés és Jelszó Megerösítése attribútumok a két érték újbóli megadásához.

Mivel két mezőnk van, hogy ellenőrizzük a megfelelő egyező mezőket, adjunk hozzá kettőt @FieldsValueMatch jegyzetek a NewUserForm osztály, egyet a email értékeket, és egyet a Jelszó értékek:

@ FieldsValueMatch.List ({@FieldsValueMatch (mező = "jelszó", fieldMatch = "ellenőrizzePassword", üzenet = "A jelszavak nem egyeznek!"), @FieldsValueMatch (mező = "e-mail", fieldMatch = "ellenőrizzeEmail", üzenet = " Az e-mail címek nem egyeznek! ")}) Public class NewUserForm {private String email; privát karakterlánc verEmail; privát karakterlánc jelszó; privát karakterlánc verPassword; // szabványos kivitelező, mérőeszközök, beállítók}

A modell érvényesítéséhez a Spring MVC-ben hozzunk létre egy vezérlőt a-val / felhasználó POST leképezés, amely megkapja a NewUserForm objektummal annotált @Érvényes és ellenőrzi, hogy vannak-e érvényesítési hibák:

@Controller public class NewUserController {@GetMapping ("/ user") public String loadFormPage (Model model) {model.addAttribute ("newUserForm", new NewUserForm ()); return "userHome"; } @PostMapping ("/ user") public String submitForm (@Valid NewUserForm newUserForm, BindingResult result, Model model) {if (result.hasErrors ()) {return "userHome"; } model.addAttribute ("üzenet", "Érvényes forma"); return "userHome"; }}

9.4. Az Annotation tesztelése

Az egyéni osztályszintű kommentárunk ellenőrzéséhez írjunk a JUnit teszt, amely megfelelő információkat küld a / felhasználó végpontot, majd ellenőrzi, hogy a válasz nem tartalmaz-e hibát:

public class ClassValidationMvcTest {private MockMvc mockMvc; @A nyilvános void beállítása előtt () {this.mockMvc = MockMvcBuilders .standaloneSetup (új NewUserController ()). Build (); } @Test public void givenMatchingEmailPassword_whenPostNewUserForm_thenOk () dobja a Kivételt {this.mockMvc.perform (MockMvcRequestBuilders .post ("/ user") .accept (MediaType.TEXT_HTML). .Param ("email", "[email protected]"). ("verEmail", "[e-mail védett]") .param ("jelszó", "átadás"). param ("igazolópassz", "átadás")) .ésExpect (modell (). hibaCount (0)). állapot (). isOk ()); }}

Ezután tegyünk hozzá egy a-t is JUnit teszt, amely nem egyező információkat küld a / felhasználó végpont és állítsa be, hogy az eredmény két hibát tartalmaz:

@Test public void givenNotMatchingEmailPassword_whenPostNewUserForm_thenOk () dobja a Kivételt {this.mockMvc.perform (MockMvcRequestBuilders .post ("/ user") .accept (MediaType.TEXT_HTML) .param ("email", "[email protected]"). VerifyEmail "," [e-mail védett] ") .param (" jelszó "," átadás ") .param (" ellenőrizPassword "," passsss ")) .ésExpect (modell (). errorCount (2)) .ésExpect (állapot ( ) .isOk ()); }

10. Összegzés

Ebben a gyors cikkben bemutattuk, hogyan lehet egyéni validátorokat létrehozni egy mező vagy osztály ellenőrzéséhez és a Spring MVC-hez való bekötéshez.

Mint mindig, a cikket is megtalálhatja a Githubon.