LuckyLuke
LuckyLuke

Reputation: 49057

Does not redirect to new page specified in the managed bean

I have recently started learning Java EE 6 and I could need some help. I have made a search.xhtml page that has a form, some fields and a commandbutton. The action invokes a method in the managed bean and returns a string. However the url-field in the browser does not update to search-results.xhtml which is the other page with the results. It shows the content inside the search.xhtml page (but it seems like it get the layout and all that from the search-results.xhtml).

(it is very simple, not doing much at this time)

@ManagedBean
@RequestScoped
public class Search {

private SearchBackingBean searchBackingBean;
private ArrayList<String> list;

public Search() {
    searchBackingBean = new SearchBackingBean();
    list = new ArrayList<String>();
}

public String find() {
    return "search-results";
}

search.xhtml

<h:form>

    <h:inputText value="#{search.searchBackingBean.query}" 
                 size="60"
                 required="true"
                 requiredMessage="Please enter what you want to search for." />
    <h:commandButton value="Find" action="#{search.find}" /><br />

    <h:outputText value="Search criterias to be included in your search." /><br />
</h:form>

Upvotes: 1

Views: 1781

Answers (1)

BalusC
BalusC

Reputation: 1108632

Basically, you're sending a POST request on the very same <form action> URL as the initial page you're viewing and during postprocessing telling JSF to use the given target page to display the results. It uses internally RequestDispatcher#forward() to forward the request/response to the given destination. This takes place entirely in the server side. If you're familiar with the basic Servlet API (which JSF uses under the covers), then you should understand its working.

If you want a change in the browser address bar URL, then you basically need to change the <form action> URL to the desired URL (which isn't possible in standard JSF without manipulating the ViewHandler based on some configuration file), or to send a fullworthy redirect after POST by adding ?faces-redirect=true to the outcome.

return "search-results?faces-redirect=true";

The redirect basically instructs the webbrowser to send a new GET request on the given URL, so the URL in address bar will change. The disadvantage is, however, that all request scoped beans are garbaged and recreated (because a redirect is a new request!) and you'll thus lose the search results.

I'm not sure why you want to have the URL changed, but if you want to make it bookmarkable, then you shouldn't use <h:form> (which defaults to POST), but just a plain HTML <form> (which defaults to GET) with plain HTML inputs and button and define the parameters as <f:viewParam> in the target page so that JSF will set them in the bean associated with the target page.

E.g. in the search form:

<form action="search-results.xhtml">
    <input name="query" size="60" />
    <input type="submit" value="Find" />
</form>

and in the result page:

<f:metadata>
    <f:viewParam name="query" value="#{search.query}" required="true" requiredMessage="Please enter what you want to search for." />
    <f:event type="preRenderView" listener="#{search.find}" />
<f:metadata>

(by the way, I'd prefer to combine them in a single page and render the results conditionally using rendered attribute)

Note that your SearchBackingBean is IMO wrongly named. It's not a backing bean. It's just an entity (or POJO or DTO or whatever you'd like to name it). Your Search class is the real backing bean.

Upvotes: 2

Related Questions