我的问题更多是关于性能而不是功能。我正在处理注册表单的电子邮件字段。User
对于它的验证,我在实体中为电子邮件格式使用注释,并EmailExistValidator
在数据库中检查此电子邮件是否已被使用。
@Entity
@Table(name = "Users")
public class User {
@Column(name = "email")
@NotNull(message = "Email address required")
@Pattern(regexp = "([^.@]+)(\\.[^.@]+)*@([^.@]+\\.)+([^.@]+)", message = "Invalid email address")
private String email;
// ... (other fields and getters/setters here)
}
验证者:
@FacesValidator(value = "emailExistValidator")
public class EmailExistValidator implements Validator {
private static final String EMAIL_ALREADY_EXISTS = "This email address is already used.";
@EJB
private UserDao userDao;
@Override
public void validate(FacesContext context, UIComponent component, Object value)
throws ValidatorException {
String email = (String) value;
try {
if (email != null && userDao.findByEmail(email) != null) {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
EMAIL_ALREADY_EXISTS, null));
}
} catch (DaoException e) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(),
null);
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.addMessage(component.getClientId(facesContext), message);
}
}
}
根据我的测试,如果电子邮件未验证正则表达式模式,则仍会应用验证器。我不喜欢执行数据库查询以检查电子邮件是否存在的想法,而我已经知道这封电子邮件甚至无效。它确实会降低性能(在表单中的模糊事件上使用 ajax 时更是如此)。
我有一些猜测,但我找不到明确的答案,这就是我在这里问几个问题的原因:
将验证器与注释约束混合在一起是一件坏事吗?
在验证过程中,是否会检查每个约束,即使其中一个没有通过?(如果是,那么是所有消息(对于每个约束)都添加到
FacesContext
组件中,还是只是第一条消息?)如果问题 2 为“是”,是否有任何方法可以在未验证一个约束时强制停止验证?
如果问题 2 为否或问题 3 为是,是否在某处指定了约束/验证器的应用顺序?这个订单可以定制吗?
如果这很重要,我将 PrimeFaces 用于我的 Facelets 组件。
我知道我可以将所有内容放入验证器并随时停止,但此验证器仅用于注册表单。当用于登录时,我只会检查实体的注释约束,而不是“已经存在”部分。此外,在我看来,注释和单约束验证器比多约束验证器的内容更具可读性。