Разлика между ограниченията @NotNull, @NotEmpty и @NotBlank при проверка на Bean

1. Общ преглед

Bean Validation е стандартна спецификация за проверка, която ни позволява лесно да проверяваме обектите на домейна, като използваме набор от ограничения, декларирани под формата на пояснения .

Макар че като цяло използването на изпълненията за проверка на боб като Hibernate Validator е доста просто, струва си да се проучат някои фини - но съществени - разлики относно това как някои от тези ограничения се прилагат.

В този урок ние ще забележите разликите между @NotNull , @NotEmpty, и @NotBlank ограничения .

2. Зависимостите на Maven

За да настроим бързо работна среда и да тестваме поведението на ограниченията @NotNull , @NotEmpty и @NotBlank , първо трябва да добавим необходимите зависимости на Maven.

В този случай ще използваме Hibernate Validator, референтната имплементация на бин за валидиране на обектите на домейна ни.

Ето съответния раздел от нашия файл pom.xml :

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

Ще използваме JUnit и AssertJ в нашите модулни тестове, така че не забравяйте да проверите най-новите версии на hibernate-validator, изпълнението на GlassFish EL, junit и assertj-core на Maven Central.

3. Ограничението @NotNull

Движейки се напред, нека да приложи наивен UserNotNull клас домейн и ограничи неговото име поле с @NotNull анотация:

public class UserNotNull { @NotNull(message = "Name may not be null") private String name; // standard constructors / getters / toString }

Сега трябва да видим как всъщност работи @NotNull под капака .

За целта нека създадем прост единичен тест за класа и да проверим няколко негови екземпляра:

@BeforeClass public static void setupValidatorInstance() { validator = Validation.buildDefaultValidatorFactory().getValidator(); } @Test public void whenNotNullName_thenNoConstraintViolations() { UserNotNull user = new UserNotNull("John"); Set
    
      violations = validator.validate(user); assertThat(violations.size()).isEqualTo(0); } @Test public void whenNullName_thenOneConstraintViolation() { UserNotNull user = new UserNotNull(null); Set
     
       violations = validator.validate(user); assertThat(violations.size()).isEqualTo(1); } @Test public void whenEmptyName_thenNoConstraintViolations() { UserNotNull user = new UserNotNull(""); Set
      
        violations = validator.validate(user); assertThat(violations.size()).isEqualTo(0); } 
      
     
    

Както се очаква, ограничението @NotNull няма да позволи нулеви стойности за ограничените полета. Въпреки това полето (ите) може да е празно.

За да разберем по-добре това, нека разгледаме метода на клас NotNullValidator ' isValid () , който ограничението @NotNull използва. Изпълнението на метода е наистина тривиално:

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

Както е показано по-горе, поле (напр. CharSequence , Collection , Map или Array), ограничено с @NotNull, не трябва да е null. Празната стойност обаче е напълно законна .

4. Ограничението @NotEmpty

Сега, нека внедрим примерен клас UserNotEmpty и използваме ограничението @NotEmpty :

public class UserNotEmpty { @NotEmpty(message = "Name may not be empty") private String name; // standard constructors / getters / toString }

С клас на място, нека просто да го тестваме, като присвоим различни стойности на полето за име :

@Test public void whenNotEmptyName_thenNoConstraintViolations() { UserNotEmpty user = new UserNotEmpty("John"); Set
    
      violations = validator.validate(user); assertThat(violations.size()).isEqualTo(0); } @Test public void whenEmptyName_thenOneConstraintViolation() { UserNotEmpty user = new UserNotEmpty(""); Set
     
       violations = validator.validate(user); assertThat(violations.size()).isEqualTo(1); } @Test public void whenNullName_thenOneConstraintViolation() { UserNotEmpty user = new UserNotEmpty(null); Set
      
        violations = validator.validate(user); assertThat(violations.size()).isEqualTo(1); }
      
     
    

На @NotEmpty марките анотация използването на @NotNull класа " isValid () прилагане и допълнително проверки, че размер / дължина на приложената обекта (разбира се, това варира в зависимост от вида на обекта се валидира) е по-голяма от нула.

Накратко, това означава, че поле (напр. CharSequence , Collection , Map или Array), ограничено с @NotEmpty, не трябва да е null и неговият размер / дължина трябва да бъде по-голямо от нула .

Освен това можем да бъдем още по-ограничителни, ако използваме анотацията @NotEmpty заедно с @Size.

По този начин бихме принудили също така, че минималните и максималните размери на обекта са в рамките на посочения минимален / максимален диапазон:

@NotEmpty(message = "Name may not be empty") @Size(min = 2, max = 32, message = "Name must be between 2 and 32 characters long") private String name; 

5. Ограничението @NotBlank

По подобен начин можем да ограничим поле на клас с анотацията @NotBlank :

public class UserNotBlank { @NotBlank(message = "Name may not be blank") private String name; // standard constructors / getters / toString }

По същия начин можем да приложим единичен тест, за да разберем как работи ограничението @NotBlank :

@Test public void whenNotBlankName_thenNoConstraintViolations() { UserNotBlank user = new UserNotBlank("John"); Set
    
      violations = validator.validate(user); assertThat(violations.size()).isEqualTo(0); } @Test public void whenBlankName_thenOneConstraintViolation() { UserNotBlank user = new UserNotBlank(" "); Set
     
       violations = validator.validate(user); assertThat(violations.size()).isEqualTo(1); } @Test public void whenEmptyName_thenOneConstraintViolation() { UserNotBlank user = new UserNotBlank(""); Set
      
        violations = validator.validate(user); assertThat(violations.size()).isEqualTo(1); } @Test public void whenNullName_thenOneConstraintViolation() { UserNotBlank user = new UserNotBlank(null); Set
       
         violations = validator.validate(user); assertThat(violations.size()).isEqualTo(1); } 
       
      
     
    

В @NotBlank анотацията използва NotBlankValidator класа, която проверява дали почиства дължина на поредица от знаци не се изпразни:

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

Забавно, методът връща вярно за нулеви стойности. Така че, може да си помислим, че @NotBlank разрешава нулеви стойности, но всъщност не.

В @NotNull клас "метод isValid () се нарича след @NotBlank класа" isValid (), следователно забранява нула стойности.

По-просто казано, един низ поле ограничени с @NotBlank трябва да бъде не нищожно и почиства дължината трябва да бъде по-голяма от нула .

6. Сравнение едно до друго

Досега разгледахме задълбочено как ограниченията @NotNull , @NotEmpty и @NotBlank действат индивидуално в полетата на класа.

Нека направим бързо сравнение едно до друго, за да можем да видим от птичи поглед функционалността на ограниченията и лесно да забележим разликите им:

  • @NotNull: ограничена CharSequence , Collection , Map или Array е валидна, стига да не е null, но може да е празна
  • @NotEmpty: ограничена CharSequence , Collection , Map или Array е валидна, стига да не е нула и размерът / дължината й да е по-голяма от нула
  • @NotBlank: ограниченият низ е валиден, стига да не е нула и отрязаната дължина е по-голяма от нула

7. Заключение

В тази статия разгледахме ограниченията NotNull , @NotEmpty и @NotBlank , внедрени в Bean Validation, и подчертахме техните прилики и разлики.

Както обикновено, всички примерни кодове, показани в тази статия, са достъпни в GitHub.