我有一个很大的'项目,大表和很多关系...所以在我的表单中,我有几个选项卡,一些对话框,以及许多PrimeFaces commandButtons来管理所有带有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会丢失主要对象,因此我可以&#39 ; t重新加载页面。
我的控制器以这种方式构建:
@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
// ----------
}
&#34;汽车&#34;作为主要对象只是一个例子。
是否有任何解决方案或解决方法?
我希望在意外重新加载后保持状态。但是,它无法使用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.
先谢谢大家,仍然找到解决方案。
答案 0 :(得分:2)
我认为我知道如何解决它(它在我的项目中帮助了我)
<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");
}
}
}
&#34;在每个HTTP请求上调用preRenderView事件(是的,这也包括ajax请求!)。&#34; (c)https://stackoverflow.com/a/9844616/3163475