是否有可能重载SpringBoot的ConstraintValidator isValid方法?

时间:2018-06-19 08:10:28

标签: java spring validation spring-boot

基本上,我的服务的作用是简化电子邮件通知的传递,以实现标准化/控制。因此,我暴露了一个POST端点,它接收一个电子邮件Bean作为响应主体,其中包含接收者,发送者,cc等信息,我想验证传入bean的字段(即电子邮件地址格式)。

目前,我编写了一个自定义验证程序,用于验证电子邮件地址列表(@EmailAddresses)。有没有办法重用相同的验证器来验证“from”属性的电子邮件地址,而不是列表而不是引入另一个验证器?

我的豆子:

public class Email {

    @JsonProperty("from")
    private String from;

    @EmailAddresses
    @JsonProperty("to")
    private List<String> to;

    @EmailAddresses
    @JsonProperty("cc")
    private List<String> cc;

   // some other fields
}

我的控制器:

@RestController
public class MyController {

    @RequestMapping(value = "/", method = RequestMethod.POST)
    public String deliverEmailNotification(@Valid @RequestBody Email email) {
        // something
    }
}

我的自定义验证注释:

@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = EmailAddressesValidator.class)
public @interface EmailAddresses {

    String message() default "Must be a valid email";

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

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

验证实施:

public class EmailAddressesValidator implements 
ConstraintValidator<EmailAddresses, List<String>> {

    @Override
    public void initialize(EmailAddresses emailAddresses) {
        // do nothing
    }

    @Override
    public boolean isValid(final List<String> emails, ConstraintValidatorContext constraintValidatorContext) {
        // do something
    }
}

所以基本上我想知道是否可以做这样的事情:

public class EmailAddressesValidator implements 
ConstraintValidator<EmailAddresses, List<String>>, ConstraintValidator<EmailAddresses, String>  {

    @Override
    public void initialize(EmailAddresses emailAddresses) {
        // do nothing
    }

    @Override
    public boolean isValid(final List<String> emails, ConstraintValidatorContext constraintValidatorContext) {
        // do something
    }

    @Override
    public boolean isValid(final String email, ConstraintValidatorContext constraintValidatorContext) {
        // do something
    }
}

还是有另一种方式吗?

1 个答案:

答案 0 :(得分:0)

由于类重复错误,未能实现ConstraintValidator的两个实例。但是,通过使验证接口由两个实现类来验证,我能够实现等效的重载。

基于带有验证注释(在本例中为@EmailAddress)注释的字段类型,将启动相应的验证实现。

@Target({ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = { EmailAddressValidator.class, EmailAddressesValidator.class })
public @interface EmailAddress {

    String message() default "Must be a valid email";

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

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

字符串列表的验证实现

public class EmailAddressesValidator implements ConstraintValidator<EmailAddress, List<String>> {

    ...
}

验证字符串的实现

public class EmailAddressValidator implements ConstraintValidator<EmailAddress, String> {

    ...
}