【问题标题】:How to keep objects on JSF Flash Scope after Ajax call or Reload?Ajax 调用或重新加载后如何将对象保留在 JSF Flash Scope 上?
【发布时间】:2017-03-22 10:29:35
【问题描述】:

我有一个“大”项目、大表和很多关系...所以在我的表单中,我有几个选项卡、一些对话框和很多 PrimeFaces 命令按钮来管理所有带有 Ajax 请求的 CRUD。

xhtml 结构是这样的:

<ui:define name="content">
<h:body>
    <p:growl id="growl"/>
    <h:form id="formCars" enctype="multipart/form-data">
        <p:tabView id="formTabView" scrollable="true" >
            <p:tab title="Tab1">
                <ui:include src="tabOne/tabOne.xhtml" />
            </p:tab>
            <p:tab title="Tab2">...</p:tab>
            ...
            <p:tab title="Tab8">...</p:tab>
        </p:tabView>
        <br />
        <div align="center">
            <p:commandButton id="cmdSave" value="Save" 
                action="#{controllerMB.save}" icon="ui-icon-disk" 
                update="@form :growl" process="@form @this" validateClient="true" />
        </div>
    </h:form>

    <p:dialog header="Car Color" id="modalCarColor" widgetVar="modalCarColor" appendToBody="true" modal="true" height="500" width="700" dynamic="true" closeOnEscape="true" >
        <p:ajax event="close" listener="#{controllerMB.closeModalCarColor}" update="@this,:formCarColor"/>
        <h:form id="formCarColor">
            <ui:include src="tabTwo/carColor/carColor.xhtml" />
        </h:form>
    </p:dialog>

    <p:dialog header="Car Size" ...>
        <p:ajax event="close" .../>
        <h:form id="formCarColor">...</h:form>
    </p:dialog>

</h:body>
</ui:define>

而且它完美无瑕... 问题是当我尝试重新加载页面时...... 我设法通过使用

将主要对象保留在闪存上
FacesContext.getCurrentInstance().getExternalContext().getFlash().keep(key)

在@ViewScoped 控制器的@PostConstruct 上。 如果我访问页面并且不触摸 ajax 按钮,我可以毫无问题地重新加载页面......但是,如果我确实触摸了任何导致 ajax 请求的东西,JSF Flash Scopre 会丢失主要对象,因此我不能重新加载页面。

我的控制器是这样构建的:

@ManagedBean(name="controllerMB")
@ViewScoped
public class ControllerMB implements Serializable{
    // attributes
    // ----------
    @PostConstruct
    public void init(){

        if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
            car = (Car) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("car");
            FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
        }
        if(car==null) { 
            redirect_back();
            return;
        }

        // attributes initialization and form preparation
        // -----
    }

    // methods
    // ----------

}

作为主要对象的“汽车”只是一个例子。

是否有任何解决方案或解决方法?

我想在“意外重新加载”后保持该状态,但它不适用于 Flash。

另外,是否可以从浏览器捕获/处理重新加载事件(可能使用 js)?我的意思是,然后我可以在重新加载之前在我的主对象中处理表单。

我在我的项目中使用 PrimeFaces 5.3、JSF 2、Maven、Tomcat 7 和 Java 7。

提前谢谢大家。


编辑1:在尝试了用户NightEagle提到的解决方案后,它几乎工作了......我修改了代码:

<ui:composition ....>
    <f:metadata>
      <f:event type="preRenderView" listener="#{controllerMB.preRender}"/>
    </f:metadata>
    <ui:define name="title">...</ui:define>
    <ui:define name="header">...</ui:define>
    <ui:define name="content">...</ui:define>
</ui:composition>

public void preRender()
{
    System.out.print("PRE-RENDER ");
    if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
        System.out.println("KEEP");
        FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
    } else {
        System.out.println("PUT");
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("car",car);
    }
}

奇怪的是,第一个 ajax 调用很好,第二个之后……它开始弹出 JSF1095 错误。

一些对话框打开后的输出:

PRE-RENDER PUT
PRE-RENDER KEEP
PRE-RENDER KEEP
Jul 14, 2017 11:43:59 AM com.sun.faces.context.flash.ELFlash setCookie
WARNING: JSF1095: The response was already committed by the time we tried to set the outgoing cookie for the flash.  Any values stored to the flash will not be available on the next request.
PRE-RENDER PUT
Jul 14, 2017 11:44:00 AM com.sun.faces.context.flash.ELFlash setCookie
WARNING: JSF1095: The response was already committed by the time we tried to set the outgoing cookie for the flash.  Any values stored to the flash will not be available on the next request.
PRE-RENDER PUT
Jul 14, 2017 11:44:04 AM com.sun.faces.context.flash.ELFlash setCookie
WARNING: JSF1095: The response was already committed by the time we tried to set the outgoing cookie for the flash.  Any values stored to the flash will not be available on the next request.

提前谢谢大家,仍在寻找解决方案。

【问题讨论】:

    标签: javascript ajax jsf primefaces


    【解决方案1】:

    我认为我知道如何解决它(它在我的项目中帮助了我)

    <f:metadata>
      <f:event type="preRenderView" listener="#{myBean.preRender}"/>
    </f:metadata>
    

    支持的 bean:

    public class MyBean
    {
        @PostConstruct
        public void init(){
            if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
                car = (Car) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("car");
                FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
            }
        }
    
        public void preRender()
        {
            if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
                FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
            }
        }
    }
    

    “每个 HTTP 请求都会调用 preRenderView 事件(是的,这也包括 ajax 请求!)。” (c)https://stackoverflow.com/a/9844616/3163475

    【讨论】:

    • 您好,我尝试了解决方案并用结果编辑了问题,不幸的是,没有按预期工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    相关资源
    最近更新 更多