4

我创建了一个新的验证器:

package com.example.jsf.validator;

import com.example.components.LoginFormValue;
import com.example.ejb.SecurityEjb;
import java.io.Serializable;
import javax.ejb.EJB;
import javax.enterprise.context.ApplicationScoped;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import javax.inject.Named;

/**
 * Validator for {@code login-form} component.
 *
 * @author steve
 */
@Named
@ApplicationScoped
public class LoginValidator implements Validator, Serializable
{
    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException
    {
        if (value == null)
        {
            return;
        }

        LoginFormValue loginFormValue = (LoginFormValue) value;
        if (securityEjb.checkCredentials(loginFormValue.getEmailAddress(), loginFormValue.getPassword())) {
            return;
        }

        throw new ValidatorException(new FacesMessage("Incorrect email address/password"));
    }

    @EJB
    private SecurityEjb securityEjb;
}

但是当我尝试使用它时:

<my:login-form emailAddress="#{loginBean.emailAddress}"
               rememberMe="#{loginBean.rememberMe}"
               actionListener="#{loginBean.submit()}"
               recoverPasswordOutcome="recover-password"
               registerOutcome="signup">
    <f:validator validatorId="#{loginValidator}"/>
</my:login-form>

加载页面时显示此异常:

javax.faces.FacesException: Expression Error: Named Object: com.example.jsf.validator.LoginValidator@31888ef8 not found.

有问题的代码行是:

com.sun.faces.application.ApplicationImpl.createValidator(ApplicationImpl.java:1593)

为什么 JSF 可以实际解析验证器 bean 类却不能实例化它?我的应用程序中的每个其他验证器都是一个Named ApplicationScopedbean,它们都工作得很好。我引用它们都使用<f:validator validatorId="{myValidatorBean}"/>.

我正在使用 GlassFish 3.1.2。

4

2 回答 2

10

必须引用验证器的<f:validator validatorId>ID,而不是具体的验证器实例。验证器的 ID 正是您指定为@FacesValidator值或<validator-id>使用该faces-config.xml方法时指定的那个。例如

@FacesValidator("myValidator")

然后将其引用为

<f:validator validatorId="myValidator" />

validatorId在视图构建期间,任何 EL 表达式都将被解析为String标识验证器 ID。因此,当传递一个具体Validator实例时,它只会以它的toString()值结束,就像com.example.MyValidator@hashcode作为验证器 ID 传递一样,这显然不存在,因为异常消息试图告诉你:

javax.faces.FacesException:表达式错误:命名对象:com.example.jsf.validator.LoginValidator@31888ef8 未找到。

您应该使用<f:validator binding>or<h:inputText validator>代替。它可以举一个具体的例子。

<f:validator binding="#{myValidator}" />

传递给复合组件时它不起作用是另一个问题。您根本没有指定for属性,因此它不会应用于UIInput组合内的任何组件。我认为以下问题/答案将完全适用以解决该问题:如何为复合组件内的输入组件指定验证器?

于 2012-06-09T21:03:40.750 回答
0

我今天遇到了同样的问题,并通过添加“实现验证器”来解决它。那是我的错误。

<ui:composition>
    <h:inputText id="#{id}" value="#{value}" size="20">
        <f:validator validatorId="com.example.shop.validator.PhoneNumber"/>
    </h:inputText>
</ui:composition>

@FacesValidator("com.example.shop.validator.PhoneNumber")
public class PhoneNumber implements Validator {

@Override
public void validate(FacesContext facesContext, UIComponent uiComponent,     Object o) throws ValidatorException {

}
于 2017-06-22T21:53:25.847 回答