1

I was testing couple of new features of JSF and I came across Post Redirect Get. I wanted to redirect from my first page say first.xhtml to second.xhtml.

I have a number as a property in both the managed beans and I wanted to pass it to the second bean from the first bean using request parameter.

This is my first page

        <html xmlns="http://www.w3.org/1999/xhtml"
            xmlns:ui="http://java.sun.com/jsf/facelets"
            xmlns:h="http://java.sun.com/jsf/html"
            xmlns:f="http://java.sun.com/jsf/core">


        <head>
            <title>Landing Page</title>
        </head>

        <body>
        <h3>Enter Number</h3>
        <h:form>
            <h:inputText id="input" name="number" value="#{postRedirectGet.number}" />
            <h:commandButton value="redirect to result" 
    action="resultPage?faces-redirect=true&amp;includeViewParams=true">
            </h:commandButton>
        </h:form>
        </body>
        </html>

And in the second page I have

  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">
<f:metadata>
    <f:viewParam name="number" value="#{postRedirectResult.number}"/>
</f:metadata> 

<head>
    <title>Result Page</title>
</head>

<body>
<h:form>
    <h:outputText value="Number #{postRedirectGet.number}" />
    <h:outputText value="Number #{postRedirectResult.number}" />
    <h:commandButton value="Redirect to index" action="/index?faces-redirect=true" />
</h:form>
</body>
</html>

Now the page is doing a POST using commandButton and then redirecting to second page from first but it passes number=0 in the URL. It works if I change

<f:viewParam name="number" value="#{postRedirectResult.number}"/>

to

<f:viewParam name="number" value="#{postRedirectGet.number}"/>

but I thought the viewParam is used to set the value to a bean and not used to pass the values in URL. Could someone please explain how can we do POST and set the property of the managed bean on next page.

The problem is that the f:viewParam is used in two different ways in two scenarios . In h:link it is used to set the property of target bean , in h:commandButton it is used to compute the GET URL and then the target bean property can be set using @ManagedProperty . Is my understanding correct or can the f:viewParam be used to set the property in h:commandButton POST redirect get also.

Avinash Singh
  • 3,421
  • 2
  • 20
  • 21
  • 1
    Unrelated, but you probably want `h:body` and `h:head` instead of the HTML equivalents (it makes JSF happy and able to include a lot of it's JS code). – mabi May 29 '14 at 15:32

2 Answers2

2

What you seem to be missing is what includeViewParams does. Let me quote this very informative article (you should read all of it):

The other special query string parameter, includeViewParams, tells the navigation handler to include the view parameters when performing the navigation. But what view parameters should be included? The view parameters to be included when performing the navigation are declared on the to-view-id page.

So JSF looks at your resultpage.xhtml to determine which parameters to pass. And then dutifully proceeds to pass the current value of postRedirectResult#number (which at this time is unset/0).

To have the GET number parameter reflected in your bean, pass it as a real parameter:

<h:commandButton value="redirect to result" 
        action="resultPage?faces-redirect=true&amp;number=4" />

See also:

Community
  • 1
  • 1
mabi
  • 5,279
  • 2
  • 43
  • 78
  • `` will not pass the value to resultPage as GET as it will POST on the current page and then redirect to resultPage . – Avinash Singh May 29 '14 at 16:35
  • You're right, using `f:param` doesn't survive the redirect. My bad. I've tested a small sample and edited my answer to include a way that will work under PRG. Note that this will generate a *static* parameter: you can't pass a value that the user entered on the same page. Grab the value and store it a bean (so it can be forwarded via `f:viewParam` on the target page). – mabi May 29 '14 at 21:48
1

There are different 4 ways to transfer data from JSF Page To Backing Bean. We can use

  1. f:param
  2. f:setPropertyActionListener
  3. f:attribute
  4. Method expression (JSF 2.0).

Here you can try f:setPropertyActionListener as..

<h:commandButton value="redirect to result" 
        action="resultPage?faces-redirect=true">
    <f:setPropertyActionListener target="#{postRedirectResult.number}" value=4 />
</h:commandButton>

Here is the link for this.

Tunaki
  • 132,869
  • 46
  • 340
  • 423
manankhh
  • 309
  • 1
  • 4
  • 12
  • your answer will fix the issue as you are setting the property in postRedirectResult bean but it will also load both my bean on page 1 . Can I in some way do the redirect with GET and set the property on second page. – Avinash Singh May 29 '14 at 16:41
  • so what u can do is... 1)transfer your parameter with the URL to next page 2)Than on the page load after the u can call a method public void init() { // do something } and write a code to take the URL and get parameter HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest(); String clipId = request.getParameter("id"); and u can set this to the your local variable and use that variable in your next page/... – manankhh May 29 '14 at 17:16