我在这里有一个问题:
场景: 我有一个JSF-2,Spring(Beans wiring)应用程序.我写了一个自定义验证器,我想执行它.
@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");
}
}
Run Code Online (Sandbox Code Playgroud)
我试图使用以下方式注入验证器:
方法1:
<h:inputText value="#{helloWorld.name}">
<f:validator binding="#{com.test.vali}" />
</h:inputText>
Run Code Online (Sandbox Code Playgroud)
产量
当试图渲染页面时,它抛出异常.
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)
Run Code Online (Sandbox Code Playgroud)
在此搜索了很多,并验证了几种方式:
路#2
<f:validator validatorId="com.test.vali" />
Run Code Online (Sandbox Code Playgroud)
产量
javax.servlet.ServletException: Expression Error: Named Object: com.test.vali not found.
Run Code Online (Sandbox Code Playgroud)
所以从方式#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">
Run Code Online (Sandbox Code Playgroud)
验证器配置是:
<validator>
<validator-id>com.test.vali</validator-id>
<validator-class>teet.TestValidator</validator-class>
</validator>
Run Code Online (Sandbox Code Playgroud)
产量
作品
现在问题出现了,即使使用JSF-2.0,我也不得不求助于faces-config.xml.
我在做什么可能是个错误?
让我们知道是否需要更多配置.
Bal*_*usC 10
首先,您基本上混合了两种注册验证器实例的方法,它们完全独立地工作:通过注册为面验证器@FacesValidator,或者注册为CDI管理bean @Named.这些注释彼此不了解,也没有考虑到彼此.您基本上最终会得到两个完全不同的实例,这些实例不会彼此共享数据.为避免将来出现混淆,因此强烈建议删除其中一个注释,以便保证始终使用同一个实例.
至于为什么方式1失败:
@Named("com.test.vali")
public class TestValidator implements Validator {
// ...
}
Run Code Online (Sandbox Code Playgroud)
<f:validator binding="#{com.test.vali}" />
Run Code Online (Sandbox Code Playgroud)
这是因为句点.是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 {
// ...
}
Run Code Online (Sandbox Code Playgroud)
<f:validator binding="#{testValidator}" />
Run Code Online (Sandbox Code Playgroud)
至于为什么方式2失败:
@FacesValidator("com.test.vali")
public class TestValidator implements Validator {
// ...
}
Run Code Online (Sandbox Code Playgroud)
<f:validator validatorId="com.test.vali" />
Run Code Online (Sandbox Code Playgroud)
@FacesValidator在启动期间未正确拾取时可能会发生这种情况.当有问题的类不在WAR内部,而是在例如EAR或EJB内部时,这可能反过来发生.在这种情况下,您需要在中明确注册验证器faces-config.xml.但更好的方法是将类放在WAR中,您应该在项目的EAR或EJB部分中绝对没有任何JSF工件.它会将模型/服务逻辑(JPA,EJB等)紧密耦合到视图(JSF),并使其不再可用于其他视图(前端),如JAX-RS,Spring MVC,Struts2等.
| 归档时间: |
|
| 查看次数: |
4791 次 |
| 最近记录: |