我创建了一个新的验证器:
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
ApplicationScoped
bean,它们都可以正常工作。我使用<f:validator validatorId="{myValidatorBean}"/>
引用它们。
我正在使用GlassFish 3.1.2。
答案 0 :(得分:8)
<f:validator validatorId>
必须引用验证器的ID,而不是具体的验证器实例。验证程序的ID恰好是您使用@FacesValidator
方法指定为<validator-id>
值或faces-config.xml
的ID。 E.g。
@FacesValidator("myValidator")
然后被引用为
<f:validator validatorId="myValidator" />
validatorId
中的任何EL表达式在视图构建期间都会被解析为标识验证器ID的String
。因此,当传递一个具体的Validator
实例时,它只会结束其toString()
值,如com.example.MyValidator@hashcode
作为验证器ID传递,它毕竟显然不存在,因为异常消息正在尝试告诉你:
javax.faces.FacesException:Expression Error:Named Object:com.example.jsf.validator.LoginValidator@31888ef8 not found。
您应该使用<f:validator binding>
或<h:inputText validator>
代替。它可以采取具体的实例。
<f:validator binding="#{myValidator}" />
传递给复合组件时它不起作用是一个不同的问题。您根本没有指定for
属性,因此它不会应用于复合内的任何UIInput
组件。我认为以下问题/答案将完全适用于解决这个问题:How to specify a validator for an input component inside a composite component?
答案 1 :(得分:0)
我今天遇到了同样的问题,并通过添加&#34;实现Validator&#34;来解决它。那是我的错误。
<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 {
}