开发者

JSF 2.0 ViewScoped life cycle

My problem is that one of my ViewScoped bean is created several time within the same view. The constructor of ViewScopedBean is created every time I select a node in the tree.

<h:form>
    <p:tree value="#{treeBean.root}" var="node"  
        selectionMode="single" selection="#{viewScopedBean.selectedNod开发者_如何学Pythone}">  
        <p:ajax event="select" update="selectedNode, treeBeanUpdate, otherBeanUpdate, panel" listener="#{treeBean.onNodeSelect}" /> 
        <p:treeNode>  
            <h:outputText value="#{node}" />  
        </p:treeNode>  
    </p:tree>  
    Selected Node: <h:outputText value="#{viewScopedBean.selectedNode}" id="selectedNode"/><br/>
    Current TreeBean: <h:outputText value="#{treeBean}" id="treeBeanUpdate"/><br/>
    Current OtherBean: <h:outputText value="#{viewScopedBean}" id="otherBeanUpdate"/><br/>
    <p:outputPanel id="panel">
        <ag:profileComponent managedBean="#{viewScopedBean.profileBean}"/>
    </p:outputPanel>
</h:form>

If I remove this part (reference to a composite component), the constructor of ViewScopedBean is not called:

    <p:outputPanel id="panel">
        <ag:profileComponent managedBean="#{viewScopedBean.profileBean}"/>
    </p:outputPanel>

All the beans used are set as @ViewScoped.

@ManagedBean
@ViewScoped
public class ViewScopedBean implements Serializable {

    private TreeNode selectedNode;
    private ProfileBean profileBean;

    public ViewScopedBean() {
        System.out.println("Constructor of ViewScopedBean " + this);
    }

    @PostConstruct
    public void init() {
        System.out.println("ViewScoped init" + this);
        profileBean = new ProfileBean();
    }
}

Is it the correct behaviour? If not what can cause it?

Update: I tried to use an empty composite, and I have the same problem.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"      
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:composite="http://java.sun.com/jsf/composite">

      <composite:interface>
            <composite:attribute name="managedBean" required="true"/>
      </composite:interface>

      <composite:implementation>
      </composite:implementation>

</html>

But if I made the managedBean not required, that's fine.

Another thing I don't get is when the constructor is called, it seems that the object created is not used.

Initiating the view (console output):

Constructor of ViewScopedBean xxx.bean.ViewScopedBean@4e1d2b8e

2 clicks on the tree:

Constructor of ViewScopedBean xxx.bean.ViewScopedBean@4eb64f2e
Constructor of ViewScopedBean xxx.bean.ViewScopedBean@66863941

Then I open the debug window <ui:debug/>, the viewScopedBean is set to xxx.bean.ViewScopedBean@4e1d2b8e


The view scoped bean will be recreated on every request from/to the same view, when you use JSTL tags like <c:if>, <c:forEach> and so on in the view, or when you bind a JSF component as a property of the view scoped bean using binding attribute. That's apparently what's happening in your composite component.

You need to rewrite your composite component as such that it does not utilize any JSTL tags. Binding some JSF component as a property of the bean can also be avoided in many ways, but if that is really not avoidable, then disabling the partial state saving in web.xml should work in most of the cases:

<context-param>
    <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
    <param-value>false</param-value>
</context-param>

If that doesn't work for you, then you really have to share your composite component implementation code with us so that we can point out the caveats and propose the right approaches.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜