【问题标题】:can @Email and spring custom validation coexists?@Email 和 spring 自定义验证可以共存吗?
【发布时间】:2014-09-18 14:34:32
【问题描述】:

我需要在使用 Web 服务创建帐户时验证电子邮件和密码。我正在使用 Spring REST 控制器并计划使用 @Email(hibernate validator) 注释进行电子邮件 ID 验证。对于密码验证,我必须通过实现 Validator 接口来编写自定义验证器。

@XmlRootElement
public class Account implements Serializable {

    @Email(message =AccountErrorCodes.ACCOUNT_EMAIL_VALIDATION)
    private String emailId;

    private String password;

用于编写自己的验证器的密码

@Autowired
private PasswordValidator passwordValidator;

@InitBinder
private void initBinder(WebDataBinder binder) {
    binder.setValidator(passwordValidator);
}

看起来两者不能共存。当我尝试验证 EmailId 时,spring 调用 passwordValidator 但无法验证电子邮件。我预计由于电子邮件 ID 不正确而导致失败。当我禁用自定义验证器时,我会收到所需的错误消息。

看起来我错过了什么。我需要做些什么来让它工作吗?还是不支持?如果不支持,我可以直接从 spring 自定义验证器调用 Hibernate 验证器以避免为电子邮件编写自己的验证吗?

【问题讨论】:

    标签: spring hibernate-validator customvalidator


    【解决方案1】:

    与其在控制器中注入自定义验证器,不如为其创建一个特殊的 @Password 注释,将其用作验证器。从控制器中删除任何约束逻辑并在您的 DTO 类上完成所有操作。像这样的:

    @Target({ METHOD, FIELD, ANNOTATION_TYPE })
    @Retention(RUNTIME)
    @Constraint(validatedBy = PasswordValidator.class)
    public @interface Password {
        String message() default "{Invalid password}";
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    
    }
    

    您会发现大量使用您自己制作的验证器的自定义注释教程。希望对您有所帮助。

    【讨论】:

    • 通过编写我们自己的自定义注解,我还能使用 Spring 提供的返回多个错误消息的 Binding Result 对象吗?
    • 还有什么我做的不对吗?
    • 我不确定你是否可以。无论如何我不建议尝试。在控制器中拥有验证逻辑并不是一个好习惯,在两个不同的地方甚至更糟。您应该仅在您的方法签名中使用 @Valid 注释来验证您的 DTO。
    • 是的,我可以返回多个错误消息,我刚刚在 stackoverflow(stackoverflow.com/questions/13059961/…) 上找到了似乎运行良好的帖子。
    • 只是仔细检查..我想使用的场景“@Email和spring自定义验证可以共存吗?”不可能吗?
    【解决方案2】:

    你问: 通过编写我们自己的自定义注释,我是否仍然可以使用 Spring 提供的返回多个错误消息的 Binding Result 对象?

    是的。

    您可以为任何类型制作自己的自定义注释。 例如:

    电话号码

        @Phone
        @NotEmpty
        private String phone;
    

    现在制作一个java文件:

    电话.java

    import java.lang.annotation.Documented;
    import java.lang.annotation.Retention;
    import java.lang.annotation.Target;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.RetentionPolicy;
    
    import javax.validation.Constraint;
    import javax.validation.Payload;
    
    @Documented
    @Constraint(validatedBy = PhoneValidator.class)
    @Target( { ElementType.METHOD, ElementType.FIELD })
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Phone {
     
         
       String message() default "{Phone}";
         
       Class<?>[] groups() default {};
         
       Class<? extends Payload>[] payload() default {};
          
    }
    

    还有一个提供验证措施的类:

    PhoneValidator.java

    import javax.validation.ConstraintValidator;
    import javax.validation.ConstraintValidatorContext;
    
    public class PhoneValidator implements ConstraintValidator<Phone, String> {
    
        @Override
        public void initialize(Phone paramA) {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public boolean isValid(String phoneNo, ConstraintValidatorContext ctx) {
            // TODO Auto-generated method stub
            if(phoneNo == null) {
             return false;
            }
            
            //Validate phone numbers of format "1234567890"
             if (phoneNo.matches("\\d{10}")) return true;
             
            //validating phone number with -, . or spaces
            else if(phoneNo.matches("\\d{3}[-\\.\\s]\\d{3}[-\\.\\s]\\d{4}")) return true;
            
             //validating phone number with extension length from 3 to 5
            else if(phoneNo.matches("\\d{3}-\\d{3}-\\d{4}\\s(x|(ext))\\d{3,5}")) return true;
            
             //validating phone number where area code is in braces ()
            else if(phoneNo.matches("\\(\\d{3}\\)-\\d{3}-\\d{4}")) return true;
            
             //return false if nothing matches the input
            else return false;
        }
        
        
    
    }
    

    现在:

    message_en.properties

    包括:

    #Custom validation annotation
    Phone=Invalid format, valid formats are 1234567890, 123-456-7890 x1234
    

    通过这种方式,您将成功获得自定义验证器。

    绑定结果

    将捕获错误并从属性文件中获取消息。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-10
      • 2015-12-14
      • 2012-01-16
      • 2012-07-15
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      相关资源
      最近更新 更多