4

我在这里有一个问题:

场景: 我有一个 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

 <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。

可能是什么错误在做什么?

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

4

1 回答 1

10

首先,您基本上混合了两种注册验证器实例的方法,它们完全独立工作:通过注册为面部验证器@FacesValidator,或通过注册为 CDI 托管 bean @Named。那些注解彼此不认识,也不考虑彼此。您基本上会得到两个完全不同的实例,它们不共享彼此的数据。为避免将来出现混淆,因此强烈建议删除其中一个注释,以便您可以保证始终使用同一个实例。

至于为什么方式1失败:

@Named("com.test.vali")
public class TestValidator implements Validator {
    // ...
}
<f:validator binding="#{com.test.vali}" />

这是因为句.点是 EL 中的特殊运算符,表示 bean 属性访问或 bean 方法调用。Using#{com.test.vali}只会查找一个 bean #{com},然后查找它的test属性,然后再查找它的vali属性。换句话说,它基本上是试图通过com.getTest().getVali()where comis a CDI managed bean like so 来获取验证器@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 等。

于 2013-04-25T13:20:50.530 回答