自定义验证

时间:2014-12-16 21:42:07

标签: java spring validation

我想要一个自定义注释来验证表单中的电子邮件是否唯一。已经成功创建了一个" ValidEmail"注解。

@Target({ ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EmailValidatorImpl.class)
public @interface ValidEmail {
    String message() default "{error.validEmail}";
    String[] groups() default {};
}

实施班:

public class EmailValidatorImpl implements ConstraintValidator<ValidEmail, String> {

private static String EMAIL_PATTERN = "^[\\w\\.-]+@([\\w\\-]+\\.)+[A-Z]{2,4}$";
private Pattern pattern;
private Matcher matcher;

@Override
public void initialize(ValidEmail annotation) {
    pattern = Pattern.compile(EMAIL_PATTERN, Pattern.CASE_INSENSITIVE);
}

@Override
public boolean isValid(String email, ConstraintValidatorContext context) {
    return isValidEmail(email);

}

private boolean isValidEmail(String email) {
    CharSequence emailstr = email;
    matcher = pattern.matcher(emailstr);
    return matcher.matches();
}

}

我现在想建立一个&#34; uniqueEmail&#34;注释

public class UniqueEmailValidatorImpl implements ConstraintValidator<UniqueEmail, String> {

private UserServices userServices;

@Override
public void initialize(UniqueEmail annotation) {
    this.userServices = annotation.getUserServices();
}

@Override
public boolean isValid(String email, ConstraintValidatorContext context) {
    return isUniqueEmail(email);

}

private boolean isUniqueEmail(String email) {
    try {
        userServices.findByEmail(email);
    } catch (UserDoesNotExistException e) {
        return true;
    }
    return false;

}

}

由于我跟随IoC(使用Spring),我真的不想直接在initialize方法中创建用户服务层的实例。你会怎么建议解决这个问题?注释是否可以引用实例?

@Override
public void initialize(UniqueEmail annotation) {
    this.userServices = annotation.getUserServices();
}

任何建议将不胜感激。 THX!

3 个答案:

答案 0 :(得分:1)

您应该注入userServices依赖项。根据您的项目结构如何构建,这可以是自动装配,构造函数注入或注入setter。

以其他方式更严格地执行此操作,因为注释要求在其中设置的所有内容都是编译时常量,因此您只能拥有String和无论如何,Class对象在那里,你必须通过反射实例化你关心的对象。使用Spring来做这件事更有意义。

此外,您的实际验证方法是可疑的。我希望findByEmail无论用户是否通过电子邮件存在于数据库中都应该返回;也就是说,boolean。以这种方式使用try...catch似乎不合适,并且效率非常低,因为您的验证程序可能会经常被称为非常

答案 1 :(得分:1)

为什么不注入UserServices

@Autowired
private UserServices userServices;

答案 2 :(得分:1)

一般情况下,我不建议您在验证器中使用您的服务(关于MVC和副作用)。当你使用Spring时为什么不注入你的服务?

@Autowired
public void setUserService(final UserServices userServices) {
    this.userServices = userServices
}