[jsf] How do you pass view parameters when navigating from an action in JSF2?

From an action in my bean, I'm trying to redirect to another page expecting a view parameter. What is the recommended way to do this in JSF2?

E.g., say my source page is: http://localhost/page1.xhtml

it has a commandButton that calls an action:

<h:commandButton value="submit" action="#{myBean.submit}" />

where my bean looks like:

@ManagedBean
@RequestScoped
public class MyBean {

private int id;

public String submit() {
    //Does stuff
    id = setID();
    return "success";
}

And now, I want the 'submit' action's return to navigate to http://localhost/page2.xhtml?id=2

I've tried to do this with a view-param in my navigation case, but with odd results. The faces-config snippet looks like the following:

<navigation-rule>
    <from-view-id>/page1.xhtml</from-view-id>
    <navigation-case>
        <from-outcome>success</from-outcome>
        <to-view-id>/page2.xhtml</to-view-id>
        <redirect>
            <view-param>
                <name>id</name>
                <value>#{myBean.id}</value>
            </view-param>
        </redirect>
    </navigation-case>
</navigation-rule>

The weird behaviour being, even though myBean is set to request scoped, it only calls myBean.getId() the first time I load my application, and reuses that same value for all subsequent calls, producing incorrect view parameters for page2.

So I'm looking for either a better way to do this, or a reason/solution for why the view-param is not being requested from my bean each time.

This question is related to jsf jsf-2

The answer is


Check out these:

You're gonna need something like:

<h:link outcome="success">
  <f:param name="foo" value="bar"/>
</h:link>

...and...

<f:metadata>
  <f:viewParam name="foo" value="#{bean.foo}"/>
</f:metadata>

Judging from this page, something like this might be easier:

 <managed-bean>
   <managed-bean-name>blog</managed-bean-name>
   <managed-bean-class>com.acme.Blog</managed-bean-class>
   <managed-property>
      <property-name>entryId</property-name>
      <value>#{param['id']}</value>
   </managed-property>
 </managed-bean>

You can do it using Primefaces like this :

<p:button 
      outcome="/page2.xhtml?faces-redirect=true&amp;id=#{myBean.id}">
</p:button>

Without a nicer solution, what I found to work is simply building my query string in the bean return:

public String submit() {
    // Do something
    return "/page2.xhtml?faces-redirect=true&id=" + id;
}

Not the most flexible of solutions, but seems to work how I want it to.

Also using this approach to clean up the process of building the query string: http://www.warski.org/blog/?p=185


Just add the seen attribute to redirect tag as below:

<redirect include-view-params="true">
    <view-param>
        <name>id</name>
        <value>#{myBean.id}</value>
    </view-param>
</redirect>

A solution without reference to a Bean:

<h:button value="login" 
        outcome="content/configuration.xhtml?i=1" />

In my project I needed this approach:

<h:commandButton value="login" 
        action="content/configuration.xhtml?faces-redirect=true&amp;i=1"  />