重定向后Flash数据是否可以持久化?
Can the Flash data be persisted after redirection?
使用 JSF 2.1.29
在list.xhtml
<p:commandLink id="ownerViewLinkId" value="#{petOwner.firstName} #{petOwner.lastName} "
action="#{ownerAndPetListBean.viewPetOwnerFrmList(petOwner.id,petOwner.userId,0)}"
onclick="PF('progrees_db').show()"
oncomplete="PF('progrees_db').hide()"
style="color:#0080FF;">
</p:commandLink>
在listBean(viewscoped)中,
public void viewPetOwnerFrmList(String ownerIdStr, String userIdStr,
String petIdStr) {
try {
FacesContext.getCurrentInstance().getExternalContext().getFlash().put("ownerId",ownerIdStr);
FacesContext.getCurrentInstance().getExternalContext().getFlash().put("userId",userIdStr);
FacesContext.getCurrentInstance().getExternalContext().getFlash().put("petId",petIdStr);
FacesContext.getCurrentInstance().getExternalContext()
.redirect("/ownerandpets/view");
} catch (Exception e) {
log.warn("FL Warning", e);
}
}
漂亮-config.xml
<url-mapping id="ownerandpetsview">
<pattern value="/ownerandpets/view" />
<view-id value="/WEB-INF/views/ownerAndPet/OwnerAndPetsView.xhtml" />
<action onPostback="false">#{ownerAndPetViewBean.fillPage}</action>
</url-mapping>
在viewbean(viewscoped)中,
String petIdStr;
String userIdStr;
String ownerIdStr;
String firstName;
//include getters and setters
public void fillPage() {
petIdStr = (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("petId");
userIdStr = (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("userId");
ownerIdStr = (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("ownerId");
System.out.println(ownerIdStr+" "+userIdStr+" "+petIdStr);
firstName = getFromDBByOwnerId(ownerIdStr);
}
在查看页面,
<h:outputText value="#{ownerAndPetViewBean.firstName}"/>
重定向后显示名字。
刷新视图页面(通过按 f5)时,字符串 firstName 变为空,并且在 viewBean 的 fillPage 中打印的 id 字符串为空。
我需要的是刷新,我需要重新获取 ID 不能为空的 firstName。
经历过这个link
无论如何要在请求中保留闪存数据?
尝试了以下但未成功:
1.
FacesContext.getCurrentInstance().getExternalContext()
.redirect("/ownerandpets/view?faces-redirect=true");
2.
FacesContext.getCurrentInstance()
.getExternalContext().getFlash().keep("ownerId");
FacesContext.getCurrentInstance()
.getExternalContext().getFlash().keep("userId");
FacesContext.getCurrentInstance()
.getExternalContext().getFlash().keep("petId");
3.
FacesContext.getCurrentInstance().getExternalContext()
.getFlash().setKeepMessages(true);
FacesContext.getCurrentInstance().getExternalContext()
.getFlash().setRedirect(true);
在刷新调试时,ids 在 watching FacesContext.getCurrentInstance().getExternalContext().getFlash()
的 flash scope map 中存在,但在 watching FacesContext.getCurrentInstance().getExternalContext().getFlash().get("petId");
中不显示相同的 ID(见图 2)。
更新 1(答案):
根据 Xtreme Biker 的建议,将 preRenderView 添加到视图页面。
<f:event type="preRenderView" listener="#{ownerAndPetViewBean.fillPage}"/>
.
来自漂亮-config.xml,删除或评论
<action onPostback="false">#{ownerAndPetViewBean.fillPage}</action>
在 fillPage 方法中添加一个非回发检查并在托管 bean 中添加 flash.keep。
FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("ownerId");
以上方法不适用于 pretty-faces 动作标签(如果使用而不是 preRenderview),我们将得到没有值的页面。
prettyfaces 操作可能超出了当前 flash 状态的范围。不知道 pretty 操作的具体工作原理,但您需要在执行重定向的同一请求周期中设置 flash.keep
(如果使用 pretty,则由 POST-REDIRECT-GET
模式完成)。
无论如何,the docs example for pretty action shows a @RequestScoped
bean, don't know its compatibility with the View Scope and with the flash state, consequently. I personally prefer to use the f:event='preRenderView'
checking for postbacks 如果您仍在使用 JSF 2.1。如果是 JSF 2.2,则使用 f:viewAction
,无需检查回发。
另请参阅:
- How to keep JSF flash scope parameters on page reload?
使用 JSF 2.1.29
在list.xhtml
<p:commandLink id="ownerViewLinkId" value="#{petOwner.firstName} #{petOwner.lastName} "
action="#{ownerAndPetListBean.viewPetOwnerFrmList(petOwner.id,petOwner.userId,0)}"
onclick="PF('progrees_db').show()"
oncomplete="PF('progrees_db').hide()"
style="color:#0080FF;">
</p:commandLink>
在listBean(viewscoped)中,
public void viewPetOwnerFrmList(String ownerIdStr, String userIdStr,
String petIdStr) {
try {
FacesContext.getCurrentInstance().getExternalContext().getFlash().put("ownerId",ownerIdStr);
FacesContext.getCurrentInstance().getExternalContext().getFlash().put("userId",userIdStr);
FacesContext.getCurrentInstance().getExternalContext().getFlash().put("petId",petIdStr);
FacesContext.getCurrentInstance().getExternalContext()
.redirect("/ownerandpets/view");
} catch (Exception e) {
log.warn("FL Warning", e);
}
}
漂亮-config.xml
<url-mapping id="ownerandpetsview">
<pattern value="/ownerandpets/view" />
<view-id value="/WEB-INF/views/ownerAndPet/OwnerAndPetsView.xhtml" />
<action onPostback="false">#{ownerAndPetViewBean.fillPage}</action>
</url-mapping>
在viewbean(viewscoped)中,
String petIdStr;
String userIdStr;
String ownerIdStr;
String firstName;
//include getters and setters
public void fillPage() {
petIdStr = (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("petId");
userIdStr = (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("userId");
ownerIdStr = (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("ownerId");
System.out.println(ownerIdStr+" "+userIdStr+" "+petIdStr);
firstName = getFromDBByOwnerId(ownerIdStr);
}
在查看页面,
<h:outputText value="#{ownerAndPetViewBean.firstName}"/>
重定向后显示名字。 刷新视图页面(通过按 f5)时,字符串 firstName 变为空,并且在 viewBean 的 fillPage 中打印的 id 字符串为空。 我需要的是刷新,我需要重新获取 ID 不能为空的 firstName。 经历过这个link 无论如何要在请求中保留闪存数据?
尝试了以下但未成功:
1.
FacesContext.getCurrentInstance().getExternalContext()
.redirect("/ownerandpets/view?faces-redirect=true");
2.
FacesContext.getCurrentInstance()
.getExternalContext().getFlash().keep("ownerId");
FacesContext.getCurrentInstance()
.getExternalContext().getFlash().keep("userId");
FacesContext.getCurrentInstance()
.getExternalContext().getFlash().keep("petId");
3.
FacesContext.getCurrentInstance().getExternalContext()
.getFlash().setKeepMessages(true);
FacesContext.getCurrentInstance().getExternalContext()
.getFlash().setRedirect(true);
在刷新调试时,ids 在 watching FacesContext.getCurrentInstance().getExternalContext().getFlash()
的 flash scope map 中存在,但在 watching FacesContext.getCurrentInstance().getExternalContext().getFlash().get("petId");
中不显示相同的 ID(见图 2)。
更新 1(答案):
根据 Xtreme Biker 的建议,将 preRenderView 添加到视图页面。
<f:event type="preRenderView" listener="#{ownerAndPetViewBean.fillPage}"/>
.
来自漂亮-config.xml,删除或评论
<action onPostback="false">#{ownerAndPetViewBean.fillPage}</action>
在 fillPage 方法中添加一个非回发检查并在托管 bean 中添加 flash.keep。
FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("ownerId");
以上方法不适用于 pretty-faces 动作标签(如果使用而不是 preRenderview),我们将得到没有值的页面。
prettyfaces 操作可能超出了当前 flash 状态的范围。不知道 pretty 操作的具体工作原理,但您需要在执行重定向的同一请求周期中设置 flash.keep
(如果使用 pretty,则由 POST-REDIRECT-GET
模式完成)。
无论如何,the docs example for pretty action shows a @RequestScoped
bean, don't know its compatibility with the View Scope and with the flash state, consequently. I personally prefer to use the f:event='preRenderView'
checking for postbacks 如果您仍在使用 JSF 2.1。如果是 JSF 2.2,则使用 f:viewAction
,无需检查回发。
另请参阅:
- How to keep JSF flash scope parameters on page reload?