java - 无法将 JSF ViewScoped bean 作为 ManagedProperty 注入(inject) validator

标签 java jsf-2

我正在尝试将 JSF ViewScoped bean 作为 ManagedProperty 注入(inject)到实现 javax.faces.validator.Validator 的 RequestScoped bean 中。但始终会注入(inject) ViewScoped bean 的新副本。

ViewScoped Bean

@ViewScoped
@ManagedBean
public class Bean {

     private Integer count = 1;     

     private String field2;      

     public String action(){
          ++count;
          return null;
     }

     public String anotherAction(){
          return null;
     }

     //getter and setter

}

validator

@RequestScoped
@ManagedBean
public class SomeValidator implements Validator {

     public void validate(FacesContext context, UIComponent comp, Object value)
        throws ValidatorException {

           //logging bean.getCount() is always one here. Even after calling ajax action a few times

     }
     @ManagedProperty(value = "#{bean}")
     private Bean bean;
}

xhtml 页面

<!DOCTYPE html>
 <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>

</h:head>

<h:body>
   <h:form>

    <h:panelGroup layout="block" id="panel1">


        <h:commandButton type="submit" value="Action" action="#{bean.action}">
            <f:ajax render="panel1"></f:ajax>
        </h:commandButton>

        <h:outputText value="#{bean.count}"></h:outputText>

    </h:panelGroup>

    <h:panelGroup layout="block" id="panel2">

        <h:inputText type="text" value="#{bean.field1}">
            <f:validator binding="#{someValidator}" />
        </h:inputText>

    </h:panelGroup>

    <h:commandButton type="submit" value="Another Action" action="#{bean.anotherAction}">
        <f:ajax execute="panel2" render="panel2"></f:ajax>
    </h:commandButton>

 </h:form>

</h:body>

</html>

如代码中所述,即使在多次调用 ajax 操作后,记录 bean.getCount() 时始终显示一个。

但是如果我将 ViewScoped 更改为 SessionScoped,同样的情况会起作用。此外,如果我删除 RequestScoped bean 的 validator 实现并在 PostConstruct 中使用记录器,每个 ajax 请求的计数都会按预期增加。

我做错了什么吗?或者这是它应该如何工作?提前致谢

最佳答案

那是因为 binding <f:validator> 的属性在 View 构建期间进行评估。在那一刻, View 范围还不可用(这是有道理的,它仍在忙于构建......),因此将创建一个全新的 View 范围 bean,其效果与请求范围 bean 相同。在即将推出的 JSF 2.2 中,这个先有鸡还是先有蛋的问题将得到解决。

在那之前,如果您绝对肯定您需要在 validate() 中使用 View 范围的 bean方法(我宁愿寻找其他方法,例如 <f:attribute>、EJB、多字段 validator 等),那么唯一的方法就是评估 #{bean}以编程方式在里面 validate()方法本身而不是通过 @ManagedProperty 注入(inject)它.

您可以使用 Application#evaluateExpressionGet() 为此:

Bean bean = context.getApplication().evaluateExpressionGet(context, "#{bean}", Bean.class);

另见:

关于java - 无法将 JSF ViewScoped bean 作为 ManagedProperty 注入(inject) validator ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13582400/

相关文章:

java - 如何在哈希集中进行比较,如果第二个元素相等则返回第二个值?

java - 访问 TestRule 中的自定义注释

java - 为什么通过二维数组打印时显示整个对象属性

java - 从 PING 扫描中检索 MAC 地址

java - 似乎无法弄清楚如何使用 primefaces 重定向到 .xhtml

java - 如何为下面的复杂 jQuery 选择器编写 cssSelector

maven - com.sun.faces > jsf-impl 和 org.glassfish > javax.faces (2.2.4) 的差异/相等

ajax - 日历中 primefaces ajax 上的事件日期选择不起作用

jakarta-ee - 在 JSF @ViewScoped 和 WebSocket @ServerEndpoint 之间共享数据

java - 如何在 JSF 中设置 HtmlOutputTag 的值?