Forskjellen mellom @NotNull, @NotEmpty og @NotBlank begrensninger i Bean Validation
1. Oversikt
Validering av bønner er en standard valideringsspesifikasjon som lar oss enkelt validere domeneobjekter ved å bruke et sett med begrensninger deklarert i form av merknader.
Mens generelt sett er bruk av bønnevalideringsimplementeringer som Hibernate Validator ganske grei, er det verdt å utforske noen subtile - men likevel relevante - forskjeller med hensyn til hvordan noen av disse begrensningene implementeres.
I denne veiledningen, vil vi se forskjellene mellom @Ikke null, @Ikke tom, og @NotBlank begrensninger.
2. Maven-avhengighetene
Å raskt sette opp et arbeidsmiljø og teste atferden til @Ikke null, @Ikke tom, og @NotBlank begrensninger, først må vi legge til de nødvendige Maven-avhengighetene.
I dette tilfellet bruker vi Hibernate Validator, implementering av referansen til bønnevalidering, for å validere domenenes objekter.
Her er den relevante delen av vår pom.xml fil:
org.hibernate hibernate-validator 6.0.13.Final org.glassfish javax.el 3.0.0
Vi bruker JUnit og AssertJ i enhetstestene våre, så sørg for å sjekke de nyeste versjonene av dvalemodus, GlassFishs EL-implementering, junit og assertj-core på Maven Central.
3. Den @Ikke null Begrensning
La oss implementere en naiv fremover UserNotNull domene klasse og begrense dens Navn felt med @Ikke null kommentar:
offentlig klasse UserNotNull {@NotNull (message = "Navnet kan ikke være null") privat strengnavn; // standard konstruktører / getters / toString}
Nå må vi se hvordan @Ikke null fungerer faktisk under panseret.
For å gjøre det, la oss lage en enkel enhetstest for klassen og validere noen få forekomster av den:
@BeforeClass offentlig statisk ugyldighet setupValidatorInstance () {validator = Validation.buildDefaultValidatorFactory (). GetValidator (); } @Test offentlig ugyldig nårNotNullName_thenNoConstraintViolations () {UserNotNull user = new UserNotNull ("John"); Sett brudd = validator.validate (bruker); assertThat (violations.size ()). er EqualTo (0); } @Test offentlig ugyldig nårNullName_thenOneConstraintViolation () {UserNotNull user = new UserNotNull (null); Sett brudd = validator.validate (bruker); assertThat (violations.size ()). er EqualTo (1); } @Test offentlig ugyldig nårEmptyName_thenNoConstraintViolations () {UserNotNull user = new UserNotNull (""); Sett brudd = validator.validate (bruker); assertThat (violations.size ()). er EqualTo (0); }
Som forventet, @Ikke null begrensning tillater ikke nullverdier for de begrensede feltene. Likevel kan feltet (e) være tomt.
For å bedre forstå dette, la oss se på IkkeNullValidator klasse' er gyldig() metode, som @Ikke null begrensning bruker. Metodeimplementeringen er veldig triviell:
public boolean isValid (Object object) {return object! = null; }
Som vist ovenfor, et felt (f.eks. CharSequence, Samling, Kart, eller Array) begrenset med @Ikke null må ikke være null. En tom verdi er imidlertid helt lovlig.
4. Den @Ikke tom Begrensning
La oss nå implementere et utvalg UserNotEmpty klasse og bruk @Ikke tom begrensning:
offentlig klasse UserNotEmpty {@NotEmpty (message = "Navnet kan ikke være tomt") privat strengnavn; // standard konstruktører / getters / toString}
Med klassen på plass, la oss bare teste den ved å tildele forskjellige verdier til Navn felt:
@Test offentlig ugyldig nårNotEmptyName_thenNoConstraintViolations () {UserNotEmpty user = new UserNotEmpty ("John"); Sett brudd = validator.validate (bruker); assertThat (violations.size ()). erEqualTo (0); } @Test offentlig ugyldig nårEmptyName_thenOneConstraintViolation () {UserNotEmpty user = new UserNotEmpty (""); Sett brudd = validator.validate (bruker); assertThat (violations.size ()). er EqualTo (1); } @Test offentlig ugyldig nårNullName_thenOneConstraintViolation () {UserNotEmpty user = new UserNotEmpty (null); Sett brudd = validator.validate (bruker); assertThat (violations.size ()). er EqualTo (1); }
De @Ikke tom kommentar benytter seg av @Ikke null klasse' er gyldig() implementering og i tillegg sjekker at størrelsen / lengden på det leverte objektet (selvfølgelig varierer dette avhengig av typen objekt som valideres) er større enn null.
I et nøtteskall, dette betyr at et felt (f.eks. CharSequence, Samling, Kart, eller Array) begrenset med @Ikke tom må ikke være null og størrelsen / lengden må være større enn null.
I tillegg kan vi være enda mer restriktive hvis vi bruker @Ikke tom kommentar i forbindelse med @Størrelse.
Ved å gjøre dette vil vi også håndheve at objektets min- og maksstørrelsesverdier ligger innenfor det angitte min / maks-området:
@NotEmpty (melding = "Navnet kan ikke være tomt") @Size (min = 2, max = 32, melding = "Navnet må være mellom 2 og 32 tegn langt") privat strengnavn;
5. Den @NotBlank Begrensning
På samme måte kan vi begrense et klassefelt med @NotBlank kommentar:
offentlig klasse UserNotBlank {@NotBlank (message = "Navnet kan ikke være tomt") privat strengnavn; // standard konstruktører / getters / toString}
På samme måte kan vi implementere en enhetstest for å forstå hvordan @NotBlank begrensning fungerer:
@Test offentlig ugyldig nårNotBlankName_thenNoConstraintViolations () {UserNotBlank user = new UserNotBlank ("John"); Sett brudd = validator.validate (bruker); assertThat (violations.size ()). er EqualTo (0); } @Test offentlig ugyldig nårBlankName_thenOneConstraintViolation () {UserNotBlank user = new UserNotBlank (""); Sett brudd = validator.validate (bruker); assertThat (violations.size ()). er EqualTo (1); } @Test offentlig ugyldig nårEmptyName_thenOneConstraintViolation () {UserNotBlank user = new UserNotBlank (""); Sett brudd = validator.validate (bruker); assertThat (violations.size ()). er EqualTo (1); } @Test offentlig ugyldig nårNullName_thenOneConstraintViolation () {UserNotBlank user = new UserNotBlank (null); Sett brudd = validator.validate (bruker); assertThat (violations.size ()). er EqualTo (1); }
De @NotBlank merknader bruker NotBlankValidator klasse, som sjekker at en tegnsekvens trimmede lengde ikke er tom:
public boolean isValid (CharSequence charSequence, ConstraintValidatorContext constraintValidatorContext) if (charSequence == null) {return true; } returner charSequence.toString (). trim (). lengde ()> 0; }
Morsomt nok, metoden returnerer sant for nullverdier. Så vi tror kanskje det @NotBlank tillater nullverdier, men det gjør det faktisk ikke.
De @Ikke null class 'isValid () -metoden kalles etter @NotBlank class 'isValid (), og forbyr derfor nullverdier.
For å si det enkelt, en String felt begrenset med @NotBlank må ikke være null, og den trimmede lengden må være større enn null.
6. En sammenligning side om side
Så langt har vi tatt en grundig titt på hvordan @Ikke null, @Ikke tom, og @NotBlank begrensninger fungerer individuelt på klassefelt.
La oss utføre en rask side-ved-side-sammenligning, slik at vi kan se fugleperspektivet på begrensningenes funksjonalitet og enkelt se forskjellene deres:
- @Ikke null: en begrenset CharSequence, Samling, Kart, eller Array er gyldig så lenge den ikke er null, men den kan være tom
- @Ikke tom: en begrenset CharSequence, Samling, Kart, eller Array er gyldig så lenge det ikke er null og størrelsen / lengden er større enn null
- @NotBlank: en begrenset String er gyldig så lenge den ikke er null og den trimmede lengden er større enn null
7. Konklusjon
I denne artikkelen så vi på Ikke null, @Ikke tom, og @NotBlank begrensninger implementert i Bean Validation og fremhevet deres likheter og forskjeller.
Som vanlig er alle kodeeksemplene vist i denne artikkelen tilgjengelig på GitHub.