jsf - Viewscoped Managed Bean 使用 ui :composition (Mojarra 2. 2.4) 根据每个请求重新创建

标签 jsf primefaces facelets jsf-2.2

我试图理解为什么每次 ajax 调用都会重新创建 viewscoped View 。

我有一个测试用例,无需组合模板即可正常工作。

我发现问题似乎与我的问题相似,但解决方案对我不起作用,例如设置 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 中执行子字符串,仅得到 NullPointerException使用 Facelets 模板时。 (每一步看控制台)

有人可以帮忙吗?

最佳答案

这个,

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

关闭当前 View 的 JSF 状态保存。本质上,这个 JSF View 是无状态的。由于没有 View 状态,因此无法使用 View 作用域,逻辑结果是 View 作用域 bean 实例无法保存在任何地方。在请求结束时它会消失在任何地方,因此表现得像一个请求作用域的 bean。

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

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

另请参阅:

关于jsf - Viewscoped Managed Bean 使用 ui :composition (Mojarra 2. 2.4) 根据每个请求重新创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21537162/

相关文章:

google-maps - GoogleMaps 不会在 JSF 中呈现

java - :message elements with for attribute do not present messages in JSF 2

java - AJAX 请求中组件属性在 "reRender"之后未设置

jsf - 如果表未渲染,reRender 会如何表现

jsf - 将不可序列化的应用程序范围 bean 作为集群中可序列化 session 范围 bean 的托管属性注入(inject)

更新组件后 JavaScript 不起作用

javascript - Web 应用程序中的文件夹选择器 - PrimeFaces 还是 JavaScript?

jsf - primefaces-3.3.1 生日日历

java - Primefaces SelectCheckboxMenu 空值

jsf - 将列的宽度调整为 p :dataTable 中的内容