【问题标题】:Is there an annotation for java validate if the value of a field in a List of Objects is duplicated?如果对象列表中的字段值重复,是否有 java validate 的注释?
【发布时间】:2020-01-28 19:43:40
【问题描述】:

我有一个对象列表,每个对象都有一个电子邮件,我想验证该电子邮件是否在此列表中重复。

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
Father create(@PathVariable String id,
        @Valid @RequestBody Father father) {
   ...
}

父亲会有一个孩子的名单:

private List<Child> childs;

每个孩子都会收到一封电子邮件:

public class Child {
  ...

  @NotEmpty
  private String email;

  ...
}

我想验证是否有一个请求正文,其中有 2 个孩子使用相同的电子邮件。

是否可以或仅在接收和处理有效负载后进行验证?

【问题讨论】:

标签: spring-boot javax.validation


【解决方案1】:

已编辑

为了验证子电子邮件列表,您可以创建一个自定义验证。

我编写了如下的自定义验证

1- 创建名为 ChildEmailValidation 的注释

@Documented
@Constraint(validatedBy = ChildEmailValidator.class)
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface ChildEmailValidation {

    String message() default "Duplicate Email";

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

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

}

2- 为ChildEmailValidation 创建一个验证器

在这部分,您可以编写您的自定义业务进行验证。 (你可以写你的算法)

    public class ChildEmailValidator implements ConstraintValidator<ChildEmailValidation, List<Child>> {

    @Override
    public void initialize(ChildEmailValidation constraintAnnotation) {

    }

    @Override
    public boolean isValid(List<Child> childList, ConstraintValidatorContext constraintValidatorContext) {

        //Create empty mailList
        List<String> mailList = new ArrayList<>();

        //Iterate on childList
        childList.forEach(child -> {

            //Checks if the mailList has the child's email
            if (mailList.contains(child.getMail())) {

                  //Found Duplicate email
                  throw new DuplicateEmailException();

            }

            //Add the child's email to mailList (If duplicate email is not found)
            mailList.add(child.getMail());

        });


        //There is no duplicate email
        return true;
      }

    }

3- 在父类中添加@ChildEmailValidation

public class Father {

    List<Child> child;

    @ChildEmailValidation
    public List<Child> getChild() {
        return child;
    }

    public void setChild(List<Child> child) {
        this.child = child;
    }
} 

4- 将@Valid 放在控制器中的fatherDto

@RestController
@RequestMapping(value = "/test/", method = RequestMethod.POST)
public class TestController {

    @RequestMapping(value = "/test")
    public GenericResponse getFamily(@RequestBody @Valid Father fatherDto) {
        // ...
    }

}

【讨论】:

  • 谢谢你,很棒的例子。我试试看起来很简单。
【解决方案2】:

您可以使用 this documentation 上的 Hibernate 的 @UniqueElements 注释,这是基于某些元素的 equals

@UniqueElements
private List<Child> childs;

【讨论】:

  • 对不起,但我认为你的例子不适用于我的情况,因为对象不同,我可以有姓名、年龄和其他任何不同的东西,只有电子邮件重复。
  • 所以你可以使用override equals Child 的方法,然后你也可以通过 ID 和电子邮件进行匹配。这应该基于你想做的事情,亲切的问候。
  • 但它会保持沉默。如果你想抛出错误,overriding equals 不是最好的方法。
猜你喜欢
  • 1970-01-01
  • 2018-10-04
  • 1970-01-01
  • 2016-08-10
  • 2021-03-08
  • 2016-07-10
  • 2017-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多