我在这里有一个问题:
情境: 我有一个JSF-2,Spring(Beans接线)应用程序。我编写了一个自定义验证器,我想执行它。
@FacesValidator("com.test.vali")
@Named("com.test.vali")
public class TestValidator implements Validator {
@Override
public void validate(FacesContext arg0, UIComponent arg1, Object arg2) throws ValidatorException {
System.out.println("dhkdfkbhdfbkdfksdfdfk");
}
}
我试图使用以下方式注入验证器:
路#1:
<h:inputText value="#{helloWorld.name}">
<f:validator binding="#{com.test.vali}" />
</h:inputText>
输出
尝试渲染页面时,它抛出异常。
javax.servlet.ServletException: /testRichFaces.xhtml @17,48 <f:validator> A validator id was not specified. Typically the validator id is set in the constructor ValidateHandler(ValidatorConfig)
对此进行了大量搜索,并验证了几种方式:
路#2
<f:validator validatorId="com.test.vali" />
输出
javax.servlet.ServletException: Expression Error: Named Object: com.test.vali not found.
所以从方式#1和方式#2,我可以解释没有任何注释对我有用。
然后,我试图转到最后一种方法:
方式#3:在faces-config.xml中添加验证器,只是为了表明我正在使用2.0合规性:
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
验证器配置为:
<validator>
<validator-id>com.test.vali</validator-id>
<validator-class>teet.TestValidator</validator-class>
</validator>
输出
作品
现在问题出现了,即使使用JSF-2.0,我也不得不求助于faces-config.xml。
我的错误可能是什么?
让我们知道是否需要更多配置。
答案 0 :(得分:10)
首先,您基本上混合了2种注册验证器实例的方式,它们完全独立地工作:通过@FacesValidator
注册为面部验证器,或通过@Named
注册为CDI托管bean 。这些注释彼此不了解,也没有考虑到彼此。您基本上最终会得到两个完全不同的实例,这些实例不会彼此共享数据。为避免将来出现混淆,因此强烈建议删除其中一个注释,以便保证始终使用同一个实例。
至于为什么方式1失败:
@Named("com.test.vali")
public class TestValidator implements Validator {
// ...
}
<f:validator binding="#{com.test.vali}" />
这是因为句点.
是EL中的一个特殊运算符,表示bean属性访问或bean方法调用。使用#{com.test.vali}
只会查找bean #{com}
,然后查找其test
属性,然后查找其vali
属性。换句话说,它基本上是试图通过com.getTest().getVali()
获取验证器,其中com
是CDI托管bean,如@Named("com")
。
这不是你想要的。摆脱名称中的那些时期。更好,只需坚持默认实例名称testValidator
。这是最明智的选择,当然,如果你给你的课程明智的名字。
@Named
public class TestValidator implements Validator {
// ...
}
<f:validator binding="#{testValidator}" />
至于为什么方式2失败:
@FacesValidator("com.test.vali")
public class TestValidator implements Validator {
// ...
}
<f:validator validatorId="com.test.vali" />
在启动期间未正确拾取@FacesValidator
时可能会发生这种情况。当有问题的类不在WAR内部时,可能反过来发生,而在例如EAR或EJB。在这种情况下,您需要在faces-config.xml
中明确注册验证器。但更好的是将类放在WAR中,你应该绝对不在项目的EAR或EJB部分中有任何JSF工件。它会将模型/服务逻辑(JPA,EJB等)紧密耦合到视图(JSF),并使其不再可用于其他视图(前端),如JAX-RS,Spring MVC,Struts2等。