【问题标题】:Unable to inject JSF ViewScoped bean into Validator as ManagedProperty无法将 JSF ViewScoped bean 作为 ManagedProperty 注入 Validator
【发布时间】:2012-11-14 23:10:48
【问题描述】:

我正在尝试将 JSF ViewScoped bean 作为 ManagedProperty 注入到实现 javax.faces.validator.Validator 的 RequestScoped bean 中。但总是会注入 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

}

验证器

@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 请求的计数都会按预期增加。

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

【问题讨论】:

    标签: java jsf-2


    【解决方案1】:

    这是因为&lt;f:validator&gt;binding 属性是在视图构建时评估的。在那一刻,视图范围还不可用(这是有道理的,它仍在忙于构建......),因此将创建一个全新的视图范围 bean,它与请求范围 bean 具有相同的效果。在即将到来的 JSF 2.2 中,这个先有鸡还是先有蛋的问题将得到解决。

    在此之前,如果您绝对肯定需要在 validate() 方法中使用视图范围的 bean(我宁愿寻找其他方法,例如 &lt;f:attribute&gt;、EJB、多字段验证器等),那么唯一的方法就是在validate() 方法本身内部以编程方式评估#{bean},而不是通过@ManagedProperty 注入它。

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

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

    另见:

    【讨论】:

    • 我已阅读链接的答案至少十次。但是忘记点赞了。今天不行。 ;) 谢谢。
    猜你喜欢
    • 2015-04-15
    • 1970-01-01
    • 2011-07-07
    • 2014-02-14
    • 2012-12-20
    • 1970-01-01
    • 2011-06-08
    • 1970-01-01
    • 2012-02-14
    相关资源
    最近更新 更多