Verschil tussen @NotNull, @NotEmpty en @NotBlank Beperkingen in Bean Validation

1. Overzicht

Bean Validatie is een standaard validatiespecificatie waarmee we domeinobjecten eenvoudig kunnen valideren door een reeks beperkingen te gebruiken die zijn gedeclareerd in de vorm van annotaties.

Hoewel het gebruik van bean-validatie-implementaties zoals Hibernate Validator over het algemeen redelijk eenvoudig is, is het de moeite waard om enkele subtiele - maar relevante - verschillen te onderzoeken met betrekking tot hoe sommige van deze beperkingen worden geïmplementeerd.

In deze tutorial we zullen de verschillen tussen de @Niet nul, @Niet leeg, en @RTLnieuws beperkingen.

2. De afhankelijkheden van Maven

Om snel een werkomgeving op te zetten en het gedrag van de @Niet nul, @Niet leeg, en @RTLnieuws beperkingen, moeten we eerst de vereiste Maven-afhankelijkheden toevoegen.

In dit geval gebruiken we Hibernate Validator, de referentie-implementatie voor bean-validatie, voor het valideren van onze domeinobjecten.

Hier is het relevante gedeelte van onze pom.xml het dossier:

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

We zullen JUnit en AssertJ gebruiken in onze unit-tests, dus zorg ervoor dat je de nieuwste versies van hibernate-validator, GlassFish's EL-implementatie, junit en assertj-core op Maven Central controleert.

3. Het @Niet nul Beperking

Laten we vooruitgaan, laten we een naïef implementeren UserNotNull domeinklasse en beperk zijn naam veld met de @Niet nul annotatie:

openbare klasse UserNotNull {@NotNull (bericht = "Naam mag niet null zijn") privé Stringnaam; // standard constructors / getters / toString}

Nu moeten we zien hoe @Niet nul werkt eigenlijk onder de motorkap.

Om dit te doen, maken we een eenvoudige unit-test voor de klas en valideren we een paar voorbeelden ervan:

@BeforeClass openbare statische ongeldige setupValidatorInstance () {validator = Validation.buildDefaultValidatorFactory (). GetValidator (); } @Test openbare ongeldigheid whenNotNullName_thenNoConstraintViolations () {UserNotNull gebruiker = nieuwe UserNotNull ("John"); Set violations = validator.validate (gebruiker); assertThat (violations.size ()). isEqualTo (0); } @Test openbare leegte whenNullName_thenOneConstraintViolation () {UserNotNull gebruiker = nieuwe UserNotNull (null); Set violations = validator.validate (gebruiker); assertThat (violations.size ()). isEqualTo (1); } @Test openbare leegte whenEmptyName_thenNoConstraintViolations () {UserNotNull gebruiker = nieuwe UserNotNull (""); Set violations = validator.validate (gebruiker); assertThat (violations.size ()). isEqualTo (0); } 

Zoals verwacht, de @Niet nul beperking staat geen null-waarden toe voor de beperkte velden. Toch kunnen de velden leeg zijn.

Laten we, om dit beter te begrijpen, eens kijken naar het NotNullValidator klasse' is geldig() methode, die de @Niet nul beperking gebruikt. De implementatie van de methode is echt triviaal:

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

Zoals hierboven getoond, een veld (bijv. CharSequence, Verzameling, Kaart, of Matrix) beperkt met @Niet nul mag niet nul zijn. Een lege waarde is echter volkomen legaal.

4. Het @Niet leeg Beperking

Laten we nu een voorbeeld implementeren UserNotEmpty class en gebruik de @Niet leeg beperking:

openbare klasse UserNotEmpty {@NotEmpty (bericht = "Naam mag niet leeg zijn") privé Stringnaam; // standard constructors / getters / toString}

Laten we, met de klasse op zijn plaats, deze testen door verschillende waarden toe te wijzen aan het naam veld:

@Test openbare leegte whenNotEmptyName_thenNoConstraintViolations () {UserNotEmpty gebruiker = nieuwe UserNotEmpty ("John"); Set violations = validator.validate (gebruiker); assertThat (violations.size ()). isEqualTo (0); } @Test openbare leegte whenEmptyName_thenOneConstraintViolation () {UserNotEmpty gebruiker = nieuwe UserNotEmpty (""); Set violations = validator.validate (gebruiker); assertThat (violations.size ()). isEqualTo (1); } @Test openbare leegte whenNullName_thenOneConstraintViolation () {UserNotEmpty gebruiker = nieuwe UserNotEmpty (null); Set violations = validator.validate (gebruiker); assertThat (violations.size ()). isEqualTo (1); }

De @Niet leeg annotatie maakt gebruik van de @Niet nul klasse' is geldig() implementatie en controleert bovendien of de grootte / lengte van het geleverde object (dit varieert natuurlijk afhankelijk van het type object dat wordt gevalideerd) groter is dan nul.

In een notendop, dit betekent dat een veld (bijv. CharSequence, Verzameling, Kaart, of Matrix) beperkt met @Niet leeg mag niet nul zijn en de grootte / lengte moet groter zijn dan nul.

Bovendien kunnen we zelfs nog restrictiever zijn als we de @Niet leeg annotatie in combinatie met @Grootte.

Daarbij dwingen we ook af dat de min- en max-groottes van het object binnen het gespecificeerde min / max-bereik vallen:

@NotEmpty (message = "Naam mag niet leeg zijn") @Size (min = 2, max = 32, message = "Naam moet tussen 2 en 32 tekens lang zijn") private String naam; 

5. Het @RTLnieuws Beperking

Evenzo kunnen we een klasseveld beperken met de @RTLnieuws annotatie:

openbare klasse UserNotBlank {@NotBlank (bericht = "Naam mag niet leeg zijn") privé Stringnaam; // standard constructors / getters / toString}

Op dezelfde manier kunnen we een unit-test implementeren om te begrijpen hoe de @RTLnieuws beperking werkt:

@Test openbare ongeldigheid whenNotBlankName_thenNoConstraintViolations () {UserNotBlank gebruiker = nieuwe UserNotBlank ("John"); Set violations = validator.validate (gebruiker); assertThat (violations.size ()). isEqualTo (0); } @Test openbare leegte whenBlankName_thenOneConstraintViolation () {UserNotBlank gebruiker = nieuwe UserNotBlank (""); Set violations = validator.validate (gebruiker); assertThat (violations.size ()). isEqualTo (1); } @Test openbare leegte whenEmptyName_thenOneConstraintViolation () {UserNotBlank gebruiker = nieuwe UserNotBlank (""); Set violations = validator.validate (gebruiker); assertThat (violations.size ()). isEqualTo (1); } @Test openbare leegte whenNullName_thenOneConstraintViolation () {UserNotBlank gebruiker = nieuwe UserNotBlank (null); Set violations = validator.validate (gebruiker); assertThat (violations.size ()). isEqualTo (1); } 

De @RTLnieuws annotatie gebruikt de NotBlankValidator class, die controleert of de bijgesneden lengte van een tekenreeks niet leeg is:

openbare boolean isValid (CharSequence charSequence, ConstraintValidatorContext constraintValidatorContext) if (charSequence == null) {return true; } retourneer charSequence.toString (). trim (). length ()> 0; } 

Grappig genoeg retourneert de methode true voor null-waarden. Dus dat denken we misschien @RTLnieuws staat null-waarden toe, maar in feite niet.

De @Niet nul class 'isValid () methode wordt genoemd na de @RTLnieuws class 'isValid (), waardoor null-waarden worden verboden.

Simpel gezegd, een Draad veld beperkt met @RTLnieuws mag niet nul zijn en de bijgesneden lengte moet groter zijn dan nul.

6. Een vergelijking naast elkaar

Tot nu toe hebben we diepgaand gekeken naar hoe de @Niet nul, @Niet leeg, en @RTLnieuws beperkingen werken afzonderlijk op klassevelden.

Laten we een snelle vergelijking uitvoeren, zodat we de functionaliteit van de beperkingen in vogelvlucht kunnen bekijken en hun verschillen gemakkelijk kunnen herkennen:

  • @Niet nul: een beperkt CharSequence, Verzameling, Kaart, of Array is geldig zolang het niet null is, maar het kan leeg zijn
  • @Niet leeg: een beperkt CharSequence, Verzameling, Kaart, of Array is geldig zolang het niet nul is en de grootte / lengte groter is dan nul
  • @NotBlank: een beperkt Draad is geldig zolang het niet nul is en de bijgesneden lengte groter is dan nul

7. Conclusie

In dit artikel hebben we gekeken naar de Niet nul, @Niet leeg, en @RTLnieuws beperkingen geïmplementeerd in Bean Validation en benadrukten hun overeenkomsten en verschillen.

Zoals gewoonlijk zijn alle codevoorbeelden die in dit artikel worden getoond, beschikbaar op GitHub.