Question

Mojarra 2.1.26

I have a very simple page:

hello.xml:

<h:head></h:head>

<f:metadata>
    <f:viewParam name="name"></f:viewParam>
</f:metadata>

<h:body>
    <h1>Hello #{param.name} !!!</h1>
</h:body>

And another page index.html. On this page I have a commandLink which triggers POST request:

<h:commandLink value="Go to hello page" action="/pages/hello.xhtml" >
    <f:param name="name" value="Hubert" />
</h:commandLink>

This works. I can see statement: Hello Hubert !!!

Question:

This unfortunately does not work with redirection:

<h:commandLink value="Go to hello page" action="/pages/hello.xhtml?faces-redirect=true" >
    <f:param name="name" value="Hubert" />
</h:commandLink>

Could someone explain me why please?

Was it helpful?

Solution

To answer this question we need to know how redirect works.

Redirect

Client HTTP request is received. Reponse for this request is created. It always looks the same. Code 302 is returned, and header Location is set. For example:

HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://stackoverflow.com
...

When client received this response then it does another request. This time GET request to URI from Location header.

Question example explanation

h:commandLink triggres POST request. Response is created. This response contains URI from action:

HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://localhost:8080/myapp/pages/hello.xhtml
...

Param name is included, but it is in message body.

When client receives code 302 and Location it does the same as always. Creates GET request:

GET /myapp/pages/hello.xhtml HTTP/1.1

Simply POST reponse body is ignored. There is no reason to get content from body and attach it to GET request. That's why example from question doesn't work properly.

Solution 1: (based on LaurentG suggstion)

includeViewParams can be used. But it includes only values from elements f:viewParam. So on the same page with commandButton we have to add such element:

<h:head></h:head>

<f:metadata>
    <f:viewParam name="name"></f:viewParam>
</f:metadata>

<h:body>
    <h:form>
        <h:commandLink value="Go to hello page" action="/pages/hello.xhtml?faces-redirect=true&amp;includeViewParams=true" >
            <f:param name="name" value="Hubert" />
        </h:commandLink>
    </h:form>
</h:body>

So we have f:viewParam element on page hello.xhtml and this page that redirects to page hello.xhtml.

Solution 2:

If parameter value is from controller then we can remove element f:viewParam from page with h:commandButton. Trick can be done inside action method:

 <h:form>
        <h:commandLink value="Go to hello page" action="#{controller.action}" />
 </h:form>

And action():

public String action() {

    String outcome = "/pages/hello?faces-redirect=true";

    try {
        outcome += String.format("&amp;name=%s", URLEncoder.encode(name, "UTF-8"));
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }


    return outcome;
}

Solution 1 and 2 cretes response:

HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://localhost:8080/myapp/pages/hello.xhtml?name=Hubert
...

That's what we need.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top