Sometimes I see JSF URL is *.jsf, sometimes *.xhtml and sometimes /faces/*. Why?
Asked Answered
S

1

60

Been try to learn JSF, and sometimes I see the URL is *.jsf and sometimes is *.xhtml or /faces/*. Can someone fill my knowledge, please? When I create a JSF using Facelet, the file extension is .xhtml, so where does .jsf URL extension come from?

Synn answered 9/6, 2010 at 17:48 Comment(0)
P
105

The .jsf extension is where the FacesServlet is during the JSF 1.2 period often mapped on in the web.xml.

<servlet-mapping>
    <servlet-name>facesServlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
</servlet-mapping>

The .xhtml extension is of the actual Facelets file as you've physically placed in the webcontent of your webapp, e.g. Webapp/WebContent/page.xhtml.

If you invoke this page with the .jsf extension, e.g. http://localhost:8080/webapp/page.jsf then the FacesServlet will be invoked, locate the page.xhtml file and parse/render its JSF components. If the FacesServlet isn't invoked, then the enduser would end up getting the raw XHTML source code (which can be seen by rightclick, View Source).

Sometimes a *.faces extension or /faces/* foldermapping is been used. But this was from back in the JSF 1.0/1.1 ages. You're free to choose and use whatever mapping you'd like to let FacesServlet listen on, even if it's a nothing-saying *.xyz. The actual page itself should always have the .xhtml extension, but this is configureable by the following <context-param> in web.xml:

<context-param>
    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    <param-value>.xml</param-value>
</context-param>

This will change the FacesServlet to locate page.xml instad of (default) page.xhtml.

More recently, with JSF/Facelets 2.0 a *.xhtml mapping is been used. In JSF/Facelets 1.x it was not possible to use the same mapping extension as the physical file. It would result in an infinite loop. But since JSF/Facelets 2.0 it is possible and this allows you to call the page by http://localhost:8080/webapp/page.xhtml.

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

This way you don't need to configure some security restrictions to hide the raw source files away for cases whenever the enduser changes for example .jsf in URL to .xhtml in browser address bar. Only tooling (IDEs and plugins) and learning resources still need to catch up the advocated move from *.jsf to *.xhtml. As per JSF 2.3, the FacesServlet will by default be autoregistered on *.xhtml too (next to /faces/*, *.faces and *.jsf). This is backported to Mojarra 2.2.11.

See also:

Profluent answered 9/6, 2010 at 18:1 Comment(4)
I see, could you show me how the mapping taking place in web.xmlSynn
When the servletcontainer starts up, it parses web.xml, loads all servlets, remembers the mappings and then on every request it will check if the url matches the servlet mapping and then invoke the servlet. Also see this answer for a rough example.Profluent
This answer is so good, it should probably be in the Java EE manual :)Beckwith
@Bailey: it's actually explained in the Servlets chapter. So, learning JSF basically prerequires basic knowledge of Servlets. However, that is in case of Java EE 6 tutorial treated later than JSF (chapter 15 while JSF is treated in chapter 4).Profluent

© 2022 - 2024 — McMap. All rights reserved.