Viewscoped Managed Bean使用ui:composition(Mojarra 2.2.4)在每个请求上重新创建

时间:2014-02-03 20:33:42

标签: jsf primefaces facelets jsf-2.2

我试图理解为什么在每个ajax调用上都会重新创建视图状态视图。

我有一个测试用例,并且没有组合模板就可以正常工作。

我发现的问题与我的问题类似,但解决方案对我不起作用,例如将javax.faces.PARTIAL_STATE_SAVING设置为false或javax.faces.STATE_SAVING_METHOD设置为客户端。

以下是一个示例:

page.xhtml

<?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:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui"
    xmlns:ui="http://java.sun.com/jsf/facelets"
>

<h:body>
    <h:form id="pageForm">

        <p:commandButton 
            value="Choose an option..."
            actionListener="#{pageController.handleOptionChoose}" 
            update="selectedOption"
        />

        <br/>

        <h:panelGrid columns="2" cellpadding="3">
            <p:outputLabel for="selectedOption" value="Selected option: "/>
            <p:outputLabel id="selectedOption" value="#{pageController.selectedOption}"/>
        </h:panelGrid>

        <br/><br/>  

        <p:commandButton 
            value="Edit option"
            actionListener="#{pageController.doAnythingWithTheOption}" 
            update="editedOption"
        />

        <br/>

        <h:panelGrid columns="2" cellpadding="3">
            <p:outputLabel for="editedOption" value="Edited option: "/>
            <p:outputLabel id="editedOption" value="#{pageController.editedOption}"/>
        </h:panelGrid>

    </h:form>

    <p:dialog 
        id="dialogOption_Dialog" 
        header="Choose an option" 
        widgetVar="dialogOption_Widget"
        modal="true"
        appendTo="@(body)"
    >
        <h:form id="dialogOption_Form">
            <h:panelGrid columns="1">

                <p:selectOneButton id="dialogOptionChoose" value="#{pageController.selectedOption}" >
                    <f:selectItem itemLabel="Option 1" itemValue="Option 1" />
                    <f:selectItem itemLabel="Option 2" itemValue="Option 2" />
                    <f:selectItem itemLabel="Option 3" itemValue="Option 3" />
                </p:selectOneButton>

                <p:spacer width="0" height="20" />

                <p:commandButton 
                    value="Done"
                    action="#{pageController.showOption}"
                    update=":pageForm:selectedOption"
                    oncomplete="dialogOption_Widget.hide();"
                />

            </h:panelGrid>
        </h:form>  
    </p:dialog>

</h:body>

</html>

content.xhtml

<?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:h="http://java.sun.com/jsf/html"
    xmlns:c="http://java.sun.com/jstl/core"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:mj="http://mojarra.dev.java.net/mojarra_ext"
    xmlns:o="http://omnifaces.org/ui"
    xmlns:of="http://omnifaces.org/functions">
<h:body>
    <ui:composition template="/layout.xhtml">
        <ui:define name="content">
            <ui:include src="page.xhtml" />
        </ui:define>
    </ui:composition>
</h:body>

</html>

layout.xhtml

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui"
      xmlns:o="http://omnifaces.org/ui"
      xmlns:of="http://omnifaces.org/functions">

    <f:view contentType="text/html" transient="true">
        <h:head>
            <h:outputStylesheet name="theme.css" library="css" />
            <f:facet name="first">
                <f:metadata>
                    <meta http-equiv="X-UA-Compatible" content="IE=8" />
                </f:metadata>
                <title>Teste</title>
                <link rel="icon" type="image/png" href="resources/css/icons/favicon.ico" />
            </f:facet>
        </h:head>


        <h:body>
            <p:layout fullPage="true" >

                <p:layoutUnit id="top" position="north" size="50" style="border: 2px solid Black !important;">
<!--                <ui:insert name="menubar" /> -->
                </p:layoutUnit>

                <p:layoutUnit id="center" position="center" style="border: 2px solid Black !important;">
                    <ui:insert name="content" />
                </p:layoutUnit>

                <p:layoutUnit id="bottom" position="south" size="60" resizable="true" collapsible="true" style="border: 2px solid Black !important;">
<!--                <ui:insert name="footer" /> -->
                </p:layoutUnit>

            </p:layout>

        </h:body>

    </f:view>
</html>

PageController.java

package com.ericsantanna.grendel.mBeans;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import org.primefaces.context.RequestContext;

/**
 * @author Eric Sant'Anna
 *
 */
@ManagedBean
@ViewScoped
public class PageController {

    private String selectedOption;

    private String editedOption;

    public PageController() {
        System.out.println("RECREATING VIEW");
    }

    public void showOption()    {
        System.out.println("Selected option number: " + selectedOption.substring(7));
    }

    public void doAnythingWithTheOption()   {
        System.out.print("Trying to a substring in the selected option: ");
        editedOption = selectedOption.substring(7);
        System.out.println(editedOption);
    }

    public void handleOptionChoose()    {
        RequestContext.getCurrentInstance().execute("dialogOption_Widget.show();");
    }

    public String getSelectedOption() {
        return selectedOption;
    }

    public void setSelectedOption(String selectedOption) {
        this.selectedOption = selectedOption;
    }

    public String getEditedOption() {
        return editedOption;
    }

    public void setEditedOption(String editedOption) {
        this.editedOption = editedOption;
    }

}

JBoss日志(设置):

17:45:29,494 INFO  [org.jboss.ejb.client] (MSC service thread 1-7) JBoss EJB Client version 1.0.5.Final
17:45:29,550 INFO  [javax.enterprise.resource.webcontainer.jsf.config] (MSC service thread 1-8) Inicializando Mojarra 2.2.4 ( 20131003-1354 https://svn.java.net/svn/mojarra~svn/tags/2.2.4@12574) para o contexto '/JobSchedulerWeb'
17:45:30,344 INFO  [org.hibernate.validator.util.Version] (MSC service thread 1-8) Hibernate Validator 4.2.0.Final
17:45:30,367 INFO  [org.primefaces.webapp.PostConstructApplicationEventListener] (MSC service thread 1-8) Running on PrimeFaces 4.0
17:45:30,368 INFO  [org.omnifaces.eventlistener.VersionLoggerEventListener] (MSC service thread 1-8) Using OmniFaces version 1.5

要重现此代码,只需选择一个选项并单击“编辑选项”在辅助bean中执行子字符串,仅在使用facelets模板时获得NullPointerException。 (在每个步骤中查看控制台)

任何人都可以提供帮助吗?

1 个答案:

答案 0 :(得分:2)

此,

<f:view ... transient="true">

关闭当前视图的JSF状态保存。从本质上讲,这个JSF视图是无状态。由于没有视图状态,因此无法查看范围,逻辑结果是视图范围的bean实例无法保存在任何位置。它会在请求结束时在任何地方消失,因此就像请求范围的bean一样。

因此完全可以预期观察到的症状。如果那不是您的意图,那么您需要删除transient="true"属性。它默认为false

这与模板完全无关。 <ui:composition>在这里没有重要作用。将模板合并到没有<ui:composition><ui:define>等的单个模板时,您会遇到完全相同的问题,同时保留相同的标记。

另见: