自定义验证程序类不起作用

时间:2013-04-25 12:11:48

标签: java jsf-2 cdi

我在这里有一个问题:

情境: 我有一个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)

对此进行了大量搜索,并验证了几种方式:

  1. Java文件在一个包中。
  2. 路#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。

    我的错误可能是什么?

    让我们知道是否需要更多配置。

1 个答案:

答案 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等。