Can the Flash data be persisted after redirection?
Asked Answered
A

1

2

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).

Values in Flash Map on Refresh - Fig 1 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.

Athletic answered 30/9, 2015 at 11:2 Comment(5)
Please, add the JSF version/impl which you're usingInfallible
I have updated the question.. Using JSF 2.1.29.Athletic
Don't know how Prettyfaces handles its actions. Instead, what I recommend you is to call ViewBean#fillPage in a preRenderView 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 invoke flash.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
yes..it works when uesd preRenderView..:)Athletic
Wanted to post a loong comment, posted as an answer instead ;-)Infallible
I
1

The prettyfaces action is probably out of the scope of the current flash state. Don't know exactly how the pretty action works, but you need to set flash.keep in the same request cycle where the redirection is performed (If using pretty, that's done by a POST-REDIRECT-GET pattern).

Anyway, as 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 if you still in JSF 2.1. If JSF 2.2, use f:viewAction, without having to check for postbacks.

See also:

Infallible answered 1/10, 2015 at 9:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.