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.


$config[zx-auto] not found$config[zx-overlay] not found