Forskelle i @Valid og @Validated Annotations in Spring

1. Oversigt

I denne hurtige vejledning fokuserer vi på forskellene mellem @Gyldig og @Valideret kommentarer til foråret.

Validering af brugernes input er en almindelig funktionalitet i de fleste af vores applikationer. I Java Ecosystem bruger vi specifikt Java Standard Bean Validation API til at understøtte dette. Desuden er dette også godt integreret med Spring fra version 4.0 og fremefter. Det @Gyldig og @Valideret annoteringer stammer fra denne Standard Bean API.

Lad os i de næste sektioner se nærmere på dem.

2. @Gyldig og @Valideret Kommentarer

Om foråret bruger vi JSR-303 @Gyldig kommentar til validering af metodeniveau. Desuden bruger vi den også til at markere en medlemsattribut til validering. Denne kommentar understøtter dog ikke gruppevalidering.

Grupper hjælper med at begrænse de begrænsninger, der anvendes under validering. En særlig brugssag er UI-guider. Her i det første trin kan vi have en bestemt undergruppe af felter. I det efterfølgende trin kan der være en anden gruppe, der tilhører den samme bønne. Derfor er vi nødt til at anvende begrænsninger på disse begrænsede felter i hvert trin, men @Gyldig understøtter ikke dette.

I dette tilfælde, for gruppeniveau er vi nødt til at bruge Spring's @Valideret, som er en variant af denne JSR-303 @Gyldig. Dette bruges på metodeniveau. Og til markering af medlemsattributter bruger vi fortsat @Gyldig kommentar.

Lad os nu dykke lige ind og se på brugen af ​​disse kommentarer med et eksempel.

3. Eksempel

Lad os overveje en simpel brugerregistreringsformular, der er udviklet ved hjælp af Spring Boot. Til at begynde med har vi kun navn og adgangskode egenskaber:

offentlig klasse UserAccount {@NotNull @Size (min = 4, max = 15) privat strengadgangskode; @NotBlank privat strengnavn; // standardkonstruktører / settere / getters / toString} 

Lad os derefter se på controlleren. Her har vi den gemBasicInfo metode med @Gyldig kommentar til validering af brugerindgangen:

@RequestMapping (værdi = "/ saveBasicInfo", metode = RequestMethod.POST) offentlig streng saveBasicInfo (@Valid @ModelAttribute ("useraccount") UserAccount useraccount, BindingResult result, ModelMap model) {if (result.hasErrors ()) {return " fejl"; } returner "succes"; }

Lad os nu teste denne metode:

@Test offentlig ugyldighed givenSaveBasicInfo_whenCorrectInput_thenSuccess () kaster undtagelse {this.mockMvc.perform (MockMvcRequestBuilders.post ("/ saveBasicInfo") .accept (MediaType.TEXT_HTML) .param ("navn", "test123"). "pass")) .ogExpect (view (). name ("success")) .andExpect (status (). isOk ()). og gør (print ()); }

Efter at have bekræftet, at testen kører med succes, lad os nu udvide funktionaliteten. Det næste logiske trin er at konvertere dette til en registreringsformular i flere trin, som det er tilfældet med de fleste guider. Det første skridt med navn og adgangskode forbliver uændret. I det andet trin henter vi yderligere oplysninger som f.eks alder og telefon. Derfor opdaterer vi vores domæneobjekt med disse yderligere felter:

offentlig klasse UserAccount {@NotNull @Size (min = 4, max = 15) privat strengadgangskode; @NotBlank privat strengnavn; @Min (værdi = 18, meddelelse = "Alder bør ikke være mindre end 18") privat int alder; @NotBlank privat strengtelefon; // standardkonstruktører / settere / getters / toString} 

Denne gang bemærker vi dog, at den tidligere test mislykkes. Dette er fordi vi ikke passerer i alder og telefon felter, som stadig ikke er på billedet på brugergrænsefladen. For at understøtte denne adfærd har vi brug for gruppevalidering og @Valideret kommentar.

Til dette er vi nødt til at gruppere felterne og skabe to forskellige grupper. Først skal vi oprette to markørgrænseflader. En separat en for hver gruppe eller hvert trin. Vi kan henvise til vores artikel om gruppevalidering for den nøjagtige implementering af dette. Lad os her fokusere på forskellene i kommentarerne.

Vi får den BasicInfo interface til det første trin og AdvanceInfo til det andet trin. Desuden opdaterer vi vores Brugerkonto klasse til at bruge disse markørgrænseflader som følger:

offentlig klasse UserAccount {@NotNull (grupper = BasicInfo.class) @Size (min = 4, max = 15, grupper = BasicInfo.class) privat strengadgangskode; @NotBlank (grupper = BasicInfo.class) privat strengnavn; @Min (værdi = 18, meddelelse = "Alder bør ikke være mindre end 18", grupper = AdvanceInfo.class) privat alder; @NotBlank (grupper = AdvanceInfo.class) privat strengtelefon; // standardkonstruktører / settere / getters / toString} 

Derudover opdaterer vi nu vores controller til at bruge @Valideret kommentar i stedet for @Gyldig:

@RequestMapping (værdi = "/ saveBasicInfoStep1", metode = RequestMethod.POST) offentlig streng saveBasicInfoStep1 (@Validated (BasicInfo.class) @ModelAttribute ("useraccount") UserAccount useraccount, BindingResult result, ModelMap modelas) (hvis resultat. Fejl) )) {return "fejl"; } returner "succes"; }

Som et resultat af denne opdatering kører vores test nu med succes. Lad os nu også teste denne nye metode:

@Test offentlig ugyldighed givenSaveBasicInfoStep1_whenCorrectInput_thenSuccess () kaster undtagelse {this.mockMvc.perform (MockMvcRequestBuilders.post ("/ saveBasicInfoStep1") .accept (MediaType.TEXT_HTML). "Parameter" "". "" "". " "pass")). ogExpect (view (). name ("success")). andExpect (status (). isOk ()). andDo (print ()); }

Også dette kører med succes. Derfor kan vi se hvordan brugen af @Valideret er afgørende for gruppevalidering.

Lad os derefter se hvordan @Gyldig er afgørende for at udløse validering af indlejrede attributter.

4. Brug @Gyldig Kommentar til markering af indlejrede objekter

Det @Gyldig kommentar bruges især til at markere indlejrede attributter. Dette udløser validering af det indlejrede objekt. Lad os f.eks. I vores nuværende scenarie oprette en UserAddress objekt:

offentlig klasse UserAddress {@NotBlank privat String countryCode; // standardkonstruktører / settere / getters / toString}

For at sikre validering af dette indlejrede objekt dekorerer vi attributten med @Gyldig kommentar:

offentlig klasse UserAccount {// ... @Valid @NotNull (grupper = AdvanceInfo.class) privat UserAddress brugeradresse; // standardkonstruktører / settere / getters / toString}

5. Fordele og ulemper

Lad os se på nogle af fordele og ulemper ved at bruge @Gyldig og @Valideret kommentarer til foråret.

Det @Gyldig annotation sikrer validering af hele objektet. Det er vigtigt, at den udfører validering af hele objektgraferne. Dette skaber dog problemer for scenarier, der kun behøver delvis validering.

På den anden side kan vi bruge @Valideret til gruppevalidering, herunder ovenstående delvalidering. Men i dette tilfælde skal de validerede enheder kende valideringsreglerne for alle de grupper eller brugssager, det bruges i. Her blander vi bekymringer, derfor kan dette resultere i et antimønster.

6. Konklusion

I denne hurtige vejledning undersøgte vi de vigtigste forskelle mellem @Gyldig og @Valideret Kommentarer.

For at konkludere bruger vi JSR til enhver grundlæggende validering @Gyldig kommentar i vores metodeopkald. På den anden side skal vi bruge Spring's til enhver gruppevalidering, inklusive gruppesekvenser @Valideret kommentar i vores metodeopkald. Det @Gyldig annotering er også nødvendig for at udløse validering af indlejrede egenskaber.

Som altid er koden præsenteret i denne artikel tilgængelig på GitHub.