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.

Community
  • 1
  • 1
mehere
  • 1,487
  • 5
  • 28
  • 50
  • Please, add the JSF version/impl which you're using – Aritz Oct 01 '15 at 08:41
  • I have updated the question.. Using JSF 2.1.29. – mehere Oct 01 '15 at 08:46
  • 1
    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](http://stackoverflow.com/a/25057753/1199132) to see how to keep them directly from EL, but you could do the same from the managed bean in java code. – Aritz Oct 01 '15 at 08:55
  • yes..it works when uesd preRenderView..:) – mehere Oct 01 '15 at 09:26
  • Wanted to post a loong comment, posted as an answer instead ;-) – Aritz Oct 01 '15 at 09:39

1 Answers1

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:

Community
  • 1
  • 1
Aritz
  • 30,971
  • 16
  • 136
  • 217