Using JSF 2.1.29
In 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>
In 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);
}
}
pretty-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>
In 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);
}
In view page,
<h:outputText value="#{ownerAndPetViewBean.firstName}"/>
firstName is displayed after redirect. On refreshing the view page (by pressing f5), the string firstName becomes null and id strings printed in viewBean's fillPage is null. What i need is on refresh, i need to refetch firstName for which the ids must not be null. Had gone through this link Anyway to persist the flash data in request?
Tried the below but was not successful :
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);
On Refresh debugging, the ids are there in the flash scope map on watching FacesContext.getCurrentInstance().getExternalContext().getFlash()
, but the same is not displayed in watching FacesContext.getCurrentInstance().getExternalContext().getFlash().get("petId");
(see fig 2).
Update 1 (Answer):
As suggested by Xtreme Biker, added preRenderView to the view page.
<f:event type="preRenderView" listener="#{ownerAndPetViewBean.fillPage}"/>
.
From the pretty-config.xml, remove or comment
<action onPostback="false">#{ownerAndPetViewBean.fillPage}</action>
Put a not postback checking in fillPage method and added flash.keep in managed bean.
FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("ownerId");
The above method will not work with pretty-faces action tag (if used instead of preRenderview) and we will get page with no values.
ViewBean#fillPage
in apreRenderView
event in the facelet when you're loading your view (check there if the incoming request is a postback or not, and perform only when it's not). Then, there invokeflash.keep
, which should do the job you're looking for. Have a look to this to see how to keep them directly from EL, but you could do the same from the managed bean in java code. – Infallible