我可以使用JSF标记中指定的选项创建JSF Validator吗?

Ala*_*ect 3 validation jsf jsf-2

例如:我有一个JSF验证器来验证电子邮件:

@FacesValidator(value="validateEmail")
public class Email implements Validator
{

private static final String EMAIL_REGEXP =
        "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";

@Override
public void validate(FacesContext context, UIComponent c, Object val) throws ValidatorException
{
    String email = (String) val;
    Pattern mask = null;
    mask = Pattern.compile(EMAIL_REGEXP);
    Matcher matcher = mask.matcher(email);

    if (!matcher.matches()) {
        FacesMessage message = new FacesMessage();
        message.setDetail("Must be of the form xxx@yyy.zzz");
        message.setSummary("E-mail Addresss not valid");
        message.setSeverity(FacesMessage.SEVERITY_ERROR);
        throw new ValidatorException(message);
    }
}
}
Run Code Online (Sandbox Code Playgroud)

如果用户未输入电子邮件,此验证器将抛出异常.但有时我想让电子邮件成为可选字段.有没有办法做到这一点,不需要我写一个不同的验证器?

理想情况下,我希望它检查使用它的JSF标记中的某个参数.

Bal*_*usC 10

要回答您的具体问题,您可以使用<f:attribute>哪个包含在同一个组件中.

<h:inputText>
    <f:validator validatorId="validateEmail" />
    <f:attribute name="foo" value="bar" />
</h:inputText>
Run Code Online (Sandbox Code Playgroud)

validate()方法内部,它可以通过UIComponent#getAttributes()第二个UIComponent参数获得.

String foo = component.getAttributes().get("foo"); // bar
Run Code Online (Sandbox Code Playgroud)

但是,在您的特定情况下,更好的解决方案是return在值为null或为空时让验证器.

if (email == null || email.isEmpty()) {
    return;
}
Run Code Online (Sandbox Code Playgroud)

在JSF 1.x中,这不是必需的,因为当输入为null或为空时,不会调用验证器.但是在JSF 2.x中,为了支持JSR303 bean验证,这已经改变了.因此,如果要跳过空字段的验证,则需要在每个JSF中进行检查Validator.

请注意,当你有这个 web.xml

<context-param>
    <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
    <param-value>true</param-value>
</context-param>
Run Code Online (Sandbox Code Playgroud)

然后你可以安全地省略email.isEmpty()检查中的部分,因为它总是null而不是空字符串.


具体问题无关,你在那里的模式已经过时了.这些天,电子邮件地址中允许使用 unicode字符.

private static final String EMAIL_REGEXP = "([^.@]+)(\\.[^.@]+)*@([^.@]+\\.)+([^.@]+)";
Run Code Online (Sandbox Code Playgroud)

(注意^并且$是不必要的,因为Pattern已经隐式使用它)

此外,我还建议Pattern#compile()直接对static final变量进行操作.编译模式相对昂贵,并且Pattern实例无论如何都是线程安全的.

private static final Pattern EMAIL_PATTERN = Pattern.compile(EMAIL_REGEXP);
Run Code Online (Sandbox Code Playgroud)