Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSF 2.0 navigation not working properly

I am trying to get started with JSF 2.0. I am trying a basic navigation example and it's not working properly.

The file structure is the following:

enter image description here

I have configured the mapping in web.xml:

<!-- Change to "Production" when you are ready to deploy -->
<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
</context-param>

<!-- Welcome page -->
<welcome-file-list>
    <welcome-file>index.xhtml</welcome-file>
</welcome-file-list>

<!-- JSF mapping -->
<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

And the index page has 2 buttons which take you to different pages when clicked

The faces-config.xml file defines some navigation cases:

<!-- Configuration of navigation rules -->  
<navigation-rule>
    <from-view-id>/index.xhtml</from-view-id> 
    <navigation-case>
        <from-outcome>success</from-outcome>
        <to-view-id>/pages/success.xhtml</to-view-id>
    </navigation-case>
     <navigation-case>
        <from-outcome>error</from-outcome>
        <to-view-id>/pages/error.xhtml</to-view-id>
    </navigation-case>
</navigation-rule>

E.g. the following button should take you to the success page (/pages/success.xhtml):

<p:commandButton id="addUser" value="Add" action="#{userMB.addUser}" ajax="false"/>

I have debugged this an the return value of addUser is definitely "success".

The page switches to success.xhtml because I see the content is changed, but the browser URL points to index.xhtml....

At startup: URL is localhost:8080/PROJECT/ with no index.xhtml probably because we configured it as the welcome file. When we hit the button above, the URL becomes localhost:8080/PROJECT/index.xhtml

I believe I have messed up something with the mappings or the relative paths. I have found some advice that the only mapping should be the one with *.xhtml but I did not really understand why and how to address multiple subfolders of pages.

Any help is appreciated, thanks

like image 300
AndaP Avatar asked Dec 12 '22 21:12

AndaP


1 Answers

The page switches to success.xhtml because I see the content is changed, but the browser URL points to index.xhtml.

This is normal behaviour. The HTML <form action> points to /index.xhtml and the form will thus be submitted to exactly that URL, but behind the scenes, the response is showing the content of /pages/success.xhtml.

If you want a change in the URL, then you need to perform a redirect. You can do that by adding <redirect/> to the <navigation-case> in question.

<navigation-case>
    <from-outcome>success</from-outcome>
    <to-view-id>/pages/success.xhtml</to-view-id>
    <redirect/>
</navigation-case>

See also:

  • What is the difference between redirect and navigation/forward and when to use what?

Unrelated to the concrete problem, using navigation cases are soo JSF 1.x. Consider utilizing the new JSF 2.0 implicit navigation feature. This saves you from verbose XML hell.

public String addUser() {
    if (...) {
        return "/pages/success.xhtml?faces-redirect=true";
    } else {
        return "/pages/error.xhtml?faces-redirect=true";
    }
}

I'd however recommend just adding faces messages and then redisplaying the very same page by returning void or null instead of navigating to a "success" or "error" page, that's also how real web forms work. Unless you're doing some "Hello World", of course.

like image 51
BalusC Avatar answered Dec 20 '22 21:12

BalusC