1

I'm using JSF 2.0

this is my faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- This file is not required if you don't need any extra configuration. -->
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">

    <navigation-rule>
        <from-view-id>/pages/test/test.html</from-view-id>
        <navigation-case>
            <from-outcome>write</from-outcome>
            <to-view-id>/pages/test/test-write.html</to-view-id>
        </navigation-case>

    </navigation-rule>

</faces-config>

The TestController.java

@ManagedBean(name="testController")
@SessionScoped
public class TestController implements Serializable {

    private static final long serialVersionUID = -3244711761400747261L; 

    public String test() {


        return "write?faces-redirect=true";
}

in my test.xhtml file

<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    template="/WEB-INF/templates/default.xhtml">
    <ui:define name="content">
            <h:form>
                    <h:commandButton action="#{testController.test()}" value="test" />  
            </h:form>
    </ui:define>

</ui:composition>

and this is my web.xml

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <display-name>Bachelor Demo</display-name>      

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>
</web-app>

What am I missing?

Joergi
  • 1,527
  • 3
  • 39
  • 82

1 Answers1

9

The view IDs should not contain the FacesServlet mapping. It should represent the physical file path/name. Change .html to .xhtml. You should also remove ?faces-redirect=true and instead add a <redirect /> to the <navigation-case>.

<navigation-rule>
    <from-view-id>/pages/test/test.xhtml</from-view-id>
    <navigation-case>
        <from-outcome>write</from-outcome>
        <to-view-id>/pages/test/test-write.xhtml</to-view-id>
        <redirect />
    </navigation-case>
</navigation-rule>

By the way, this is the old JSF 1.x style. Are you aware of the new JSF2 implicit navigation? You could just return "/pages/test/test-write.xhtml?faces-redirect=true".

public String test() {
    return "/pages/test/test-write.xhtml?faces-redirect=true";
}

No need for bloated XML navigation cases anymore.

Further, if your action method is really not doing anything else, then you can also just put exactly that return value in the action attribute instead.

<h:commandButton ... action="/pages/test/test-write.xhtml?faces-redirect=true" />

Even more, if it's plain page-to-page navigation, rather use <h:link> instead. It's more SEO friendly as searchbots don't index POST forms:

<h:link ... outcome="/pages/test/test-write.xhtml" />
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • hi @BalusC, i tried both - i changed it to .xhmtl in the navigationrule - it was not working. i also deleted the navigation rule and used the `"/pages/test/test-write.xhtml?faces-redirect=true"` is the `faces-config.xml` and the `web.xml` right? – Joergi Mar 21 '12 at 16:22
  • 1
    If the rule didn't work then the from view ID just didn't match. You can learn about it by examing `facesContext.getViewRoot().getViewId()` in the action method. Note that I updated my answer with the suggestion to remove `?faces-redirect`. Further I'm not sure if I understand your last question. That string is supposed to be just the `return` value of the action method. – BalusC Mar 21 '12 at 16:24
  • 1
    Oh, the action would not be invoked at all then. You could have figured that out by setting a breakpoint on the action method or by adding a sysout/logger line. By the way, if the action method doesn't contain anything else than just a return value for naviation, then you can also just put exactly that return value inside the `action` attribute instead. Even more, if it's pure page-to-page navigation, rather use `` instead w/o redirect. That's more SEO friendly. See also http://stackoverflow.com/questions/4317684/when-should-i-use-houtputlink-instead-of-hcommandlink – BalusC Mar 21 '12 at 16:54
  • thanks... and thats how i found it at the end... i feel so stupid – Joergi Mar 21 '12 at 17:10
  • by returning the file name from the method, aren't you coupling the the view and controller? I mean the guy coding the method has to tell the guy writing the .xhtml page what to name it? For guys like me trying to wear both hats, I guess it doesn't matter ! – jeff Feb 21 '13 at 22:57