У меня есть список, заполненный телом запроса. Я ожидаю статус ответа 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
]
}




Это потому, что массив/список с элементами 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 проверяет, является ли нулевым сам объект списка, а не его элементы.
Вы можете использовать аннотацию @NotNull для элементов списка:
@NotEmpty
private List<@NotNull String> values;
Обновлено:
Пример метода контроллера:
@GetMapping
public List<String> get(@RequestBody @Valid Data data) {
return data.getValues();
}
Это не работает. Те же результаты, что и в вопросе
Убедитесь, что javax.validation.constraints.NotNull импортирован, я также добавил в ответ пример метода Controller. Это намного проще, чем принятый ответ.
Спасибо за объяснение. Но везде, где я читал, говорилось, что @NotEmpty можно использовать для проверки нулевого значения и отсутствия значений в списке. что отличается в моем случае использования? Ссылка: javaee.github.io/javaee-spec/javadocs/javax/validation/…