Change URL on ajax navigation

2019-08-08 03:27发布

问题:

I have a JSF application and I want the URL in browser address bar be changed on navigation. When I'm on Home.xhtml and I submit a form, it shows the next page AppHome.xhtml, but the URL in browser address bar is not changed.

Here's the submit button:

<p:commandButton value="Connect" update="panel" id="ajax" action="#{user.check}" styleClass="ui-priority-primary"/>

Here is the navigation rule:

<navigation-rule>
    <from-view-id>/Home.xhtml</from-view-id>
    <navigation-case>
        <from-outcome>Success</from-outcome>
        <to-view-id>/AppHome.xhtml</to-view-id>
    </navigation-case>
    <navigation-case>
        <from-outcome>Failure</from-outcome>
        <to-view-id>/Home.xhtml</to-view-id>
    </navigation-case>
</navigation-rule>

How do I change the URL in browser address bar when this navigation is performed?

回答1:

The URL in browser address bar is only changed when a synchronous request is been fired on a different URL than the current request URL. An ajax request is not a synchronous request. So the URL in browser address bar will never change. Also, JSF submits the forms by default to the current URL (check the action attribute of the generated HTML <form>), so the URL will also never change on synchronous POST requests.

You need to send a synchronous GET request on a different URL in order to change the URL in browser address bar. A redirect will force a synchronous GET request. You can achieve this by adding <redirect/> entry to the <navigation-case>.

Your aversion against performing a redirect has absolutely no grounds. It's most likely caused elsewhere and thus needs to be solved elsewhere. Is it the slow page loading and/or flash of content (flickering)? This problem has in turn nothing to do with redirects and needs to be solved differently. This is to be solved by caching appropriately. Or is it that you're losing faces messages on redirect? Make use of the flash scope via Flash#setKeepMessages().

See also:

  • How to navigate in JSF? How to make URL reflect current page (and not previous one)
  • JSF page flashes during load while in project_stage development
  • JSF Cache Static Resources Filter
  • How to show faces message in the redirected page

Unrelated to the concrete problem, navigation cases are soo JSF 1.x. Are you aware of the new JSF 2.x implicit navigation feature? Make sure that you're reading up to date JSF tutorials targeted at JSF 2.x instead of the ones targeted at JSF 1.x.

You can get rid of the whole <navigation-rule> altogether if you implement the action method as follows:

public String check() {
    // ...

    if (fail) {
        return null; // Goes back to same page while keeping JSF view state.
    } else {
        return "/AppHome?faces-redirect=true";
    }
}