【问题标题】:Can a custom validator have multiple messages based on what validation failed in hibernate validator?根据休眠验证器中的验证失败,自定义验证器可以有多条消息吗?
【发布时间】:2014-02-28 17:43:22
【问题描述】:

我有一个自定义验证来检查课程中的电子邮件字段。

注解接口:

@ReportAsSingleViolation
@NotBlank
@Email
@Target({ CONSTRUCTOR, FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = CustomEmailValidator.class)
@Documented
public @interface CustomEmail {
  String message() default "Failed email validation.";

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

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

CustomEmailValidator 类:

public class CustomEmailValidator implements ConstraintValidator<CustomEmail, String> {

  public void initialize(CustomEmail customEmail) {
    // nothing to initialize
  }

  public boolean isValid(String email, ConstraintValidatorContext arg1) {
    if (email != null) {
    String domain = "example.com";
    String[] emailParts = email.split("@");

      return (emailParts.length == 2 && emailParts[1].equals(domain));
    } else {
      return false;
    }
  }
}  

我为所有自定义消息使用 ValidationMessages.properties 文件。在属性文件中,我使用以下代码引用了上述代码中的失败:

CustomEmail.email=The provided email can not be added to the account.  

问题是该错误消息用于验证期间的所有失败,因此即使用户提供了一个空白字符串,它也会打印该消息。我想要做的是,如果验证在@NotBlank 上失败,则打印“必填字段消息”,如果在@Email 上失败,则提供“无效电子邮件”消息。然后只有在自定义验证失败时才会打印CustomEmail.email 消息。同样在我的注释界面中,@NotBlank@Email 是按顺序出现还是随机运行。那么首先运行的验证会作为错误返回吗?我的验证要求它们按照列出的顺序运行 @NotBlank,然后是 @Email,然后是 CustomEmail。

【问题讨论】:

    标签: java spring hibernate-validator


    【解决方案1】:

    请注意,在您的自定义约束中没有定义顺序。即使您首先列出@NotBlank 然后@Email,也没有订单保证。 Java 本身并没有在注解中定义任何顺序。如果要定义顺序,则需要使用组和/或组序列。在这种情况下,您也不能使用组合约束,因为组合约束上的组定义被忽略。只有主要约束的组适用。

    【讨论】:

    • 正确的@Hardy,问题最终是组序列和@NotBlank@Email。 @EmersonFarrugia 也是正确的,因为删除 @ReportAsSingleViolation 将显示发生的每个错误。我通过在我应用@CustomEmail 的模型对象内定义一个组序列来解决我的问题。强制默认首先运行,自定义最后运行。我将@NotBlank@Email 移出@CustomEmail 并将它们放在班级成员身上。这意味着我的@CustomEmail 仅在默认设置失败时运行,并且为每种错误类型收到不同的消息,而不会在一个成员上出现多次失败。
    【解决方案2】:

    您可以创建一个 Enum 来定义预期错误的类型,然后使用它的值从您的配置中检索正确的错误消息。类似的东西

    /**
      <P>Defines the type of email-formatting error message.</P>
     **/
    public enum EmailErrorTypeIs {
      /**
         <P>...</P>
    
         @see  #INVALID
         @see  #OTHER
       **/
      BLANK,
      /**
         <P>...</P>
    
         @see  #BLANK
       **/
      INVALID,
      /**
         <P>...</P>
    
         @see  #BLANK
       **/
      OTHER;
    };
    

    你会这样使用:

    if(input == null  ||  input.length() == 0)  {
       throw  new IllegalArgumentException(getErrorFromConfig(EmailErrorTypeIs.BLANK));
    }  else  if...
    

    【讨论】:

      【解决方案3】:

      关闭@ReportAsSingleViolation。每次违规您都会收到ConstraintViolation,并且可以相应地工作。

      至于顺序,按照@Hardy的回答。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-09-06
        • 1970-01-01
        • 2018-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多