Reputation: 47
I have two pages myaccount.xhtml and selectbank.xhtml In my account page there is one option for recharge account in which user will enter the amount when user will press submit button then it will goto the select bank page using following bean method.
public String gotoPayMethod() {
FacesMessage doneMessage=new FacesMessage("Redirecting to Payment Type Page");
FacesContext.getCurrentInstance().addMessage(null, doneMessage);
return "SelectBank";
}
When user will goto to selectbank there user will have to submit payment method but in this page it shows the amount as null which was entered in the previous page. Both the pages are using the same bean and the scope of the bean is request scope.
So how can I access that value without passing this values through URL GET method. Just for my satisfaction I used session scope then it was working but I know thats not the proper way because I start using session scope for each pages then it will not be efficient. Thanks
Upvotes: 1
Views: 4428
Reputation: 14277
Well, if your beans are RequestScoped
than you don't have same bean for both pages. These beans are recreated for every request, so you should pass parameters. Change return statement of your gotoPayMethod()
to:
return "SelectBank?faces-redirect=true&includeViewParams=true";
and on selectbank.xhtml
add:
<f:metadata>
<f:viewParam name="amount" value="#{bean.amount}" />
</f:metadata>
Adapt this to your property and bean name.
If using parameters is not a solution you can add this parameter in the session, and remove it from session in second bean when you retrieve it:
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("amount", amount);
((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getSession().removeAttribute("amount");
Second construction for removing the attribute is necessary as Map
returned from getSessionMap()
is immutable.
Upvotes: 4
Reputation: 11742
You can use the #{flash}
object that will keep your data until the next view. This way you won't need to deal with view parameters.
Details from myaccount.xhtml
:
<h:form>
<h:outputText value="Enter amount: " />
<h:inputText value="#{flash.amount}" />
<br/>
<h:commandButton value="Go to payment method" action="#{bean.gotoPayMethod}" />
<h:form>
Bean
of both views:
@ManagedBean
@RequestScoped
public class Bean {
@ManagedProperty("#{flash}")
private Flash flash;
private int amount = -1;
public Bean () { }
public String getAmount() {
if(amount == -1) {
int val = Integer.parseInt((String)flash.get("amount"));
flash.keep("amount");
amount = val;
}
return amount;
}
public Flash getFlash() {
return flash;
}
public void setFlash(Flash flash) {
this.flash = flash;
}
public String gotoPayMethod() {
//do business job
return "SelectBank?faces-redirect=true";
}
}
Details from selectbank.xhtml
:
<h:outputText value="Amount entered by user is #{bean.amount}" />
Upvotes: 3
Reputation: 3171
Your use case is not of simple request/response cycle, the life span is more than one request response which makes it candidate for session scope.
Using hidden variable or GET parameters in URL is not good practice especially for a banking application. Where security is so important dont compromise on small memory foot print.
If flash scope map simplifies the case you can use it, but I would not go for such a thing.
Update: Forgot to mention you can check Conversation scope too.
Upvotes: 1