Forskellen mellem @NotNull, @NotEmpty og @NotBlank begrænsninger i bønnevalidering

1. Oversigt

Validering af bønner er en standardvalideringsspecifikation, der giver os mulighed for let at validere domæneobjekter ved hjælp af et sæt begrænsninger, der er erklæret i form af annoteringer.

Mens brugen af ​​implementeringer af bønnevalidering som Hibernate Validator generelt er ret ligetil, er det værd at undersøge nogle subtile - men alligevel relevante - forskelle med hensyn til, hvordan nogle af disse begrænsninger implementeres.

I denne vejledning vi ser forskellene mellem @NotNull, @NotEmpty, og @NotBlank begrænsninger.

2. Maven-afhængighederne

For hurtigt at oprette et arbejdsmiljø og teste adfærd for @NotNull, @NotEmptyog @NotBlank begrænsninger, først skal vi tilføje de krævede Maven-afhængigheder.

I dette tilfælde bruger vi Hibernate Validator, implementering af reference til bønnevalidering, til validering af vores domæneobjekter.

Her er det relevante afsnit af vores pom.xml fil:

  org.hibernate hibernate-validator 6.0.13.Final org.glassfish javax.el 3.0.0 

Vi bruger JUnit og AssertJ i vores enhedstest, så sørg for at kontrollere de nyeste versioner af dvale-validator, GlassFishs EL-implementering, junit og assertj-core på Maven Central.

3. Den @NotNull Begrænsning

Lad os implementere et naivt fremad UserNotNull domæne klasse og begrænse dens navn felt med @NotNull kommentar:

offentlig klasse UserNotNull {@NotNull (message = "Navn er muligvis ikke nul") privat Stringnavn; // standardkonstruktører / getters / toString}

Nu skal vi se hvordan @NotNull fungerer faktisk under emhætten.

Lad os lave en simpel enhedstest for klassen og validere et par forekomster af det:

@BeforeClass offentlig statisk ugyldig setupValidatorInstance () {validator = Validation.buildDefaultValidatorFactory (). GetValidator (); } @Test offentlig ugyldigt nårNotNullName_thenNoConstraintViolations () {UserNotNull user = new UserNotNull ("John"); Sæt overtrædelser = validator.validate (bruger); assertThat (violations.size ()). er EqualTo (0); } @Test offentlig ugyldig nårNullName_thenOneConstraintViolation () {UserNotNull user = new UserNotNull (null); Sæt overtrædelser = validator.validate (bruger); assertThat (violations.size ()). er EqualTo (1); } @Test offentlig ugyldigt nårEmptyName_thenNoConstraintViolations () {UserNotNull user = new UserNotNull (""); Sæt overtrædelser = validator.validate (bruger); assertThat (violations.size ()). er EqualTo (0); } 

Som forventet @NotNull begrænsning tillader ikke nulværdier for det / de begrænsede felt. Alligevel kan mark (er) være tomme.

For bedre at forstå dette, lad os se på IkkeNullValidator klasse ' er gyldig() metode, som @NotNull begrænsning bruger. Metodeimplementeringen er virkelig triviel:

public boolean isValid (Object object) {return object! = null; }

Som vist ovenfor, et felt (f.eks. CharSequence, Kollektion, Kort, eller Array) begrænset med @NotNull må ikke være nul. En tom værdi er dog helt lovlig.

4. Den @NotEmpty Begrænsning

Lad os nu implementere en prøve UserNotEmpty klasse og brug @NotEmpty begrænsning:

offentlig klasse UserNotEmpty {@NotEmpty (message = "Navnet er muligvis ikke tomt") privat Stringnavn; // standardkonstruktører / getters / toString}

Med klassen på plads, lad os bare teste den ved at tildele forskellige værdier til navn Mark:

@Test offentlig ugyldig nårNotEmptyName_thenNoConstraintViolations () {UserNotEmpty user = new UserNotEmpty ("John"); Sæt overtrædelser = validator.validate (bruger); assertThat (violations.size ()). er EqualTo (0); } @ Test offentligt ugyldigt nårEmptyName_thenOneConstraintViolation () {UserNotEmpty user = new UserNotEmpty (""); Sæt overtrædelser = validator.validate (bruger); assertThat (violations.size ()). er EqualTo (1); } @Test offentlig ugyldig nårNullName_thenOneConstraintViolation () {UserNotEmpty user = new UserNotEmpty (null); Sæt overtrædelser = validator.validate (bruger); assertThat (violations.size ()). er EqualTo (1); }

Det @NotEmpty anmærkning gør brug af @NotNull klasse ' er gyldig() implementering og kontrollerer derudover, at størrelsen / længden af ​​det leverede objekt (naturligvis varierer alt efter typen af ​​objekt, der valideres) er større end nul.

I en nøddeskal, dette betyder, at et felt (f.eks. CharSequence, Kollektion, Kort, eller Array) begrænset med @NotEmpty må ikke være nul, og dens størrelse / længde skal være større end nul.

Derudover kan vi være endnu mere restriktive, hvis vi bruger @NotEmpty kommentar i forbindelse med @Størrelse.

Ved at gøre dette, vil vi også håndhæve, at objektets min og max størrelsesværdier er inden for det specificerede min / max interval:

@NotEmpty (message = "Navnet må ikke være tomt") @Size (min = 2, max = 32, message = "Navnet skal være mellem 2 og 32 tegn langt") privat Stringnavn; 

5. Den @NotBlank Begrænsning

På samme måde kan vi begrænse et klassefelt med @NotBlank kommentar:

offentlig klasse UserNotBlank {@NotBlank (message = "Navnet er muligvis ikke tomt") privat Stringnavn; // standardkonstruktører / getters / toString}

På samme måde kan vi implementere en enhedstest for at forstå, hvordan @NotBlank begrænsning fungerer:

@Test offentlig ugyldig nårNotBlankName_thenNoConstraintViolations () {UserNotBlank user = new UserNotBlank ("John"); Sæt overtrædelser = validator.validate (bruger); assertThat (violations.size ()). er EqualTo (0); } @Test offentligt ugyldigt nårBlankName_thenOneConstraintViolation () {UserNotBlank user = new UserNotBlank (""); Sæt overtrædelser = validator.validate (bruger); assertThat (violations.size ()). er EqualTo (1); } @Test offentligt ugyldigt nårEmptyName_thenOneConstraintViolation () {UserNotBlank user = new UserNotBlank (""); Sæt overtrædelser = validator.validate (bruger); assertThat (violations.size ()). er EqualTo (1); } @Test offentlig ugyldig nårNullName_thenOneConstraintViolation () {UserNotBlank user = new UserNotBlank (null); Sæt overtrædelser = validator.validate (bruger); assertThat (violations.size ()). er EqualTo (1); } 

Det @NotBlank kommentar bruger NotBlankValidator klasse, som kontrollerer, at en tegnsekvens trimmede længde ikke er tom:

public boolean isValid (CharSequence charSequence, ConstraintValidatorContext constraintValidatorContext) if (charSequence == null) {return true; } returner charSequence.toString (). trim (). længde ()> 0; } 

Sjovt nok returnerer metoden sand for nulværdier. Så vi tror måske det @NotBlank tillader ikke nulværdier, men det gør det faktisk ikke.

Det @NotNull class 'isValid () metode kaldes efter @NotBlank klasse 'isValid (), hvorved forbud mod nulværdier.

For at sige det enkelt, -en Snor felt begrænset med @NotBlank må ikke være null, og den trimmede længde skal være større end nul.

6. En side-ved-side sammenligning

Indtil videre har vi taget et dybtgående kig på, hvordan @NotNull, @NotEmptyog @NotBlank begrænsninger fungerer individuelt på klassefelter.

Lad os udføre en hurtig side-ved-side-sammenligning, så vi kan se et fugleperspektiv af begrænsningernes funktionalitet og let få øje på deres forskelle:

  • @NotNull: en begrænset CharSequence, Kollektion, Kort, eller Array er gyldig, så længe den ikke er nul, men den kan være tom
  • @NotEmpty: en begrænset CharSequence, Kollektion, Kort, eller Array er gyldig, så længe den ikke er nul, og dens størrelse / længde er større end nul
  • @NotBlank: en begrænset Snor er gyldig, så længe det ikke er null, og den trimmede længde er større end nul

7. Konklusion

I denne artikel kiggede vi på Ikke nul, @NotEmptyog @NotBlank begrænsninger implementeret i Bean Validation og fremhævet deres ligheder og forskelle.

Som sædvanligt er alle kodeeksempler vist i denne artikel tilgængelige på GitHub.