Список, не учитывающий аннотацию @NotEmpty

У меня есть список, заполненный телом запроса. Я ожидаю статус ответа 400 BAD Request, когда в запросе передается значение No или Null. работает как положено, когда значение не передается. А вот для Null не выкидывает 400. Как заставить работать?

class data{

    @NotEmpty
    private List<@Valid String> values;

}

Тело запроса 1 -> получение статуса ответа 200. Это ожидаемо.

{
  "values": [
        "randomValue"
      ]
}

Тело запроса 2 -> получение статуса ответа 400 (VALIDATION_ERROR). Это ожидаемо.

{
 
}

Тело запроса 3 -> получение статуса ответа 400 (VALIDATION_ERROR). Это ожидаемо.

{
  "values": [
        
      ]
}

Тело запроса 4 -> получение статуса ответа 200. Ожидаемый статус 400 (VALIDATION_ERROR).

{
  "values": [
        null
      ]
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
458
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Это потому, что массив/список с элементами null не является empty. Вы можете справиться с этим, определив новую пользовательскую проверку для проверки ввода списка. См. пример ниже:

Определите новую аннотацию ValidList (вы также можете назвать ее как угодно). Обратите внимание на атрибут validatedBy — это класс, который будет выполнять фактическую проверку полей, аннотированных этой аннотацией.

import javax.validation.Constraint;
import javax.validation.Payload;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;


@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER,         
ElementType.ANNOTATION_TYPE})
@Constraint(validatedBy = ListValidator.class)
public @interface ValidList  {
    String message() default "Array/List field cannot be null";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

Определите фактический класс валидатора — проверка выполняется этим настраиваемым валидатором ListValidator (код ниже):

import java.util.List;
import java.util.Objects;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class ListValidator implements ConstraintValidator<ValidList, List<? extends Object>> {
    @Override
    public boolean isValid(List<? extends Object> list, 
    ConstraintValidatorContext context) {
        //NOTE: this condition will mark the list invalid even if there is a single null element present in the list (you can change it to fit your use-case)
        return !(list == null || list.isEmpty() || list.stream().anyMatch(Objects::isNull));
    }

    @Override
    public void initialize(ValidList constraintAnnotation) {}
}

Теперь просто используйте только что созданную аннотацию ValidList в своем классе Data:

    public class Data {
        @ValidList
        private List<@Valid String> values;

        public List<String> getValues() {
            return values;
        }

        public void setValues(List<String> values) {
            this.values = values;
        }

        public Data() {
        }

        public Data(@NotEmpty List<@Valid String> values) {
            this.values = values;
        }

    }

Спасибо за объяснение. Но везде, где я читал, говорилось, что @NotEmpty можно использовать для проверки нулевого значения и отсутствия значений в списке. что отличается в моем случае использования? Ссылка: javaee.github.io/javaee-spec/javadocs/javax/validation/…

Skul 28.11.2022 18:30
@NotEmpty проверяет, является ли нулевым сам объект списка, а не его элементы.
birca123 28.11.2022 20:17

Вы можете использовать аннотацию @NotNull для элементов списка:

@NotEmpty
private List<@NotNull String> values;

Обновлено:

Пример метода контроллера:

@GetMapping
public List<String> get(@RequestBody @Valid Data data) {
  return data.getValues();
}

Это не работает. Те же результаты, что и в вопросе

Skul 28.11.2022 18:31

Убедитесь, что javax.validation.constraints.NotNull импортирован, я также добавил в ответ пример метода Controller. Это намного проще, чем принятый ответ.

birca123 28.11.2022 20:13

Другие вопросы по теме