简体   繁体   English

列表不遵守@NotEmpty 注释

[英]List not honoring @NotEmpty annotation

I have a list that is filled with a request body.我有一个充满请求正文的列表。 I expect 400 BAD Request response status when No value or Null is passed in request.当没有值或 Null 在请求中传递时,我预计 400 BAD 请求响应状态。 is working as expected when No value is being passed.未传递任何值时按预期工作。 But for Null, it does not throw 400. How can I make it work?但是对于 Null,它不会抛出 400。我怎样才能让它工作?

class data{

    @NotEmpty
    private List<@Valid String> values;

}

Request body 1 -> getting response status 200. This is expected.请求正文 1 -> 获取响应状态 200。这是预期的。

{
  "values": [
        "randomValue"
      ]
}

Request body 2 -> getting response status 400 (VALIDATION_ERROR).请求正文 2 -> 获取响应状态 400 (VALIDATION_ERROR)。 This is expected.这是意料之中的。

{
 
}

Request body 3 -> getting response status 400 (VALIDATION_ERROR).请求正文 3 -> 获取响应状态 400 (VALIDATION_ERROR)。 This is expected.这是意料之中的。

{
  "values": [
        
      ]
}

Request body 4 -> getting response status 200. Expected status 400 (VALIDATION_ERROR).请求正文 4 ->获取响应状态 200。预期状态 400 (VALIDATION_ERROR)。

{
  "values": [
        null
      ]
}

This is because an array/list with null elements is not empty .这是因为包含null元素的数组/列表不为empty You can handle this by defining a new custom validation for validating the list input.您可以通过定义一个新的自定义验证来验证列表输入来处理这个问题。 See an example below:请参阅下面的示例:

Define a new Annotation ValidList (you can name it something else too as per your liking).定义一个新的 Annotation ValidList (您也可以根据自己的喜好将其命名为其他名称)。 Note the validatedBy attribute - this is the class that will do the actual validation for the fields annotated with this annotation.请注意validatedBy属性 - 这是 class,它将对使用此注释注释的字段进行实际验证。

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 {};
}

Define the actual validator class - validation is handled by this custom validator ListValidator (code below):定义实际验证器 class - 验证由这个自定义验证器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) {}
}

Now, just use the newly created ValidList annotation on your Data class:现在,只需在您的Data class 上使用新创建的ValidList注释:

    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;
        }

    }

You can use the @NotNull annotation for list elements:您可以对列表元素使用@NotNull注释:

@NotEmpty
private List<@NotNull String> values;

EDIT:编辑:

An example of Controller method: Controller 方法示例:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM