3

Let's use a search page and a results page for example. If i have a ViewScoped bean that handles my search page and my results page, i'm able to pass parameters through the url using something like this:

search.xhtml

<p:commandButton value="Search" type="submit" action="#{searchBacker.search}" >

backing bean

@ManagedBean(name="search")
@ViewScoped
public class searchBacker extends AbstractBacking {

  private String firstName = null;
  private String lastName = null;
  private String results = null;

  public String search() {
    return "results?faces-redirect=true&amp;includeViewParams=true";
  }

  public void getResults() {
    MyDAO dao = new MyDAO();
    results = dao.getResults(firstName, lastName);
  }

  //getters and setters
}

results.xhtml

<f:metadata>
  <f:event type="preRenderView" listener="#{searchBacker.getResults}" />
  <f:viewParam name="firstName" value="#{searchBacker.firstName}"/>
  <f:viewParam name="lastName" value="#{searchBacker.lastName}"/>
</f:metadata>

Now lets say i have two managed beans - one for the search page and one for the results page.

Will the query string still be built in the url with 2 different managed beans or does this only work when using the same managed bean for both pages?

UPDATE

I have the same <f:viewParam> on my search.xhtml and results.xhtml page, but the only difference is that my f:viewParam value points to a different backer in my results.xhtml than in my search.xhtml. When i do this, no params get passed through the url. When I point my f:viewParam value in results.xhtml to the same backer that i use in search.xhtml, the param gets passed through the url just fine, but the value doesn't exist in the results backer where i need it. If i have duplicate f:viewParams in my results.xhtml page - one with the search backer and one with the results backer, everything works fine. Is having 2 of the same f:viewParams with both managed beans the correct way to do this?

Examples:

results.xhtml - params get passed through url, but are not available in my resultsBacker

<f:metadata>
  <f:viewParam name="firstName" value="#{searchBacker.firstName}"/>
  <f:viewParam name="lastName" value="#{searchBacker.lastName}"/>
</f:metadata>

results.xhtml - no params get passed through url

<f:metadata>
  <f:viewParam name="firstName" value="#{resultsBacker.firstName}"/>
  <f:viewParam name="lastName" value="#{resultsBacker.lastName}"/>
</f:metadata>

results.xhtml - params get passed through url and are available in my resultsBacker, but seems clunky. Is this the correct way to do this or am i still missing something?

<f:metadata>
  <f:viewParam name="firstName" value="#{searchBacker.firstName}"/>
  <f:viewParam name="firstName" value="#{resultsBacker.firstName}"/>
  <f:viewParam name="lastName" value="#{searchBacker.lastName}"/>
  <f:viewParam name="lastName" value="#{resultsBacker.lastName}"/>
</f:metadata>
Aritz
  • 30,971
  • 16
  • 136
  • 217
Catfish
  • 18,876
  • 54
  • 209
  • 353
  • What exactly is your problem? You seem to be asking a rhetorical question which can easily be answered by experimenting with it yourself. Isn't your concrete problem that the `includeViewParams=true` didn't work? – BalusC Aug 04 '13 at 12:14
  • When i tried using `includeViewParams=true` with my `f:viewParam value` using the same backing bean as my search page, everything is fine, but when i change the value to a new backing bean, the parameters don't appear in the url. – Catfish Aug 04 '13 at 14:34

2 Answers2

4

I suggest you to implement two @ViewScoped managed beans, one for the search page and the other for the results page. You should also have two xhtml pages, each one related with a bean. Obviusly its page will have its own url (as it seems you're doing right now with the same bean).

You can make the second page's bean expect two parameters, firstName and lastName. After, in the preRenderView method, when parameters are already set into the second managed bean, query your DB with that values. So how to achieve the transition between the beans? An outcome should be enough.

<p:button outcome="results">
    <f:param name="firstName" value="#{searchBean.firstName}">
    <f:param name="lastName" value="#{searchBean.lastName}">
</p:button>

This makes JSF build an url with the params you need. After you can do exactly the same that you're doing right now, but using your second bean to get your params (I strongly suggest you not to use a getter method for the preRenderView method):

<f:metadata>
  <f:event type="preRenderView" listener="#{resultBacker.initialize}" />
  <f:viewParam name="firstName" value="#{resultBacker.firstName}"/>
  <f:viewParam name="lastName" value="#{resultBacker.lastName}"/>
</f:metadata>
Aritz
  • 30,971
  • 16
  • 136
  • 217
3

includeViewParams works only if both the source and target view have the desired view parameters declared as <f:viewParam>.

So, in your parituclar case, you need to put the <f:viewParam>s with very same name in both the search.xhtml and results.xhtml. Under the covers, the includeViewParams namely only grabs the view params of the current view and then only applies the ones which are also declared in the target view.

See also:


Unrelated to the concrete problem, you seem to effectively want a GET form. In that case, there is a better way for that than performing a POST-Redirect-GET with parameters. Look at the bottom of the above "See also" link.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Can you elaborate on what you mean by `only if both the source and target view have the desired view parameters`? Typically I just redirect to a page and use `includeViewParams=true` and then on the page that i redirect to, i just have the `f:viewParam` tags there. – Catfish Aug 05 '13 at 13:44
  • I clarified the answer. – BalusC Aug 05 '13 at 13:45
  • Thanks for clarifying. Please see the updated section of my question. – Catfish Aug 05 '13 at 14:46
  • The value doesn't need to be the same. Just the name. I clarified the answer more. – BalusC Aug 05 '13 at 14:48
  • Ok i'm wondering if this is a bug then because as you can see from my updated section, if i have different backing beans in the `value` of my `f:viewParam`s, nothing gets passed through the url. – Catfish Aug 05 '13 at 14:56
  • Which JSF impl/version? Can't reproduce it in Mojarra 2.1.24. – BalusC Aug 05 '13 at 15:30
  • I'm currently using Mojarra 2.0.9 because with 2.1.x I couldn't get past the error "Cannot create a session after the response has been committed". I'll try to create a simple reproduce-able case later. – Catfish Aug 05 '13 at 15:36
  • 1
    Reproduced in 2.0.9. So, you need to upgrade. As to the new problem of session+committed, this is in turn fixed in 2.1.18. See also http://stackoverflow.com/questions/8072311/illegalstateexception-cannot-create-a-session-after-the-response-has-been-commi/8072445#8072445 – BalusC Aug 05 '13 at 15:39