10

I'm developing a JSF 2 web application. For prestige purpouses I would like that every URL ends with .jsf extension. Now it ends with .xhtml. If I change it directly to .jsf in web browser address bar, then a HTTP 500 error is shown.

How can I set it to .jsf?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Tomas
  • 111
  • 1
  • 1
  • 7
  • Nowadays it's prestige purpose to end it with `.do`. – Roman C Aug 25 '12 at 09:14
  • 2
    @RomanC Wasn't .do the popular thing in 2001? (Struts 1) Nowadays not using an extension at all might be cooler ;) For JSF you can use OmniFaces or PrettyFaces for that. – Mike Braun Aug 25 '12 at 09:56
  • It's so popular as for they add it to each ISBN, for example http://shop.oreilly.com/product/9780596005726.do – Roman C Aug 25 '12 at 10:32
  • 7
    @RomanC: please stop talking nonsense. You're only confusing starters. The `*.do` is typically used in Struts1 applications. Struts1 is just one of the many MVC frameworks and not a world wide web standard or something. For JSF, typically `*.xhtml`, `*.jsf`, `*.faces` or `/faces/*` is been used. – BalusC Aug 25 '12 at 12:25

3 Answers3

17

The URL pattern of JSF pages is specified by <servlet-mapping> of the FacesServlet in web.xml. As you mentioned that .xhtml works fine, you have apparently configured it as follows:

<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>

You need to change the <url-pattern> accordingly to get the desired virtual URL extension.

<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>*.jsf</url-pattern>      
</servlet-mapping>

That's all you need to change in order to achieve the concrete functional requirement, really.

However, this puts a security problem open. The enduser can now see the raw Facelets file source code when changing the extension in the URL back from .jsf to .xhtml. You can prevent this by adding the following security constraint to web.xml:

<security-constraint>
    <display-name>Restrict access to Facelets source code.</display-name>
    <web-resource-collection>
        <web-resource-name>Facelets</web-resource-name>
        <url-pattern>*.xhtml</url-pattern>
    </web-resource-collection>
    <auth-constraint/>
</security-constraint>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • can we alternatively ease this security problem by copying our .xhtml files to WEF-INF? – abbas Oct 11 '13 at 11:14
  • 2
    @abbas: files in `/WEB-INF` are not publicly accessible. Just set JSF mapping to `*.xhtml`. No need to hassle with virtual URLs. – BalusC Oct 11 '13 at 11:15
2
 <context-param>
  <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
  <param-value>.xhtml</param-value>
 </context-param>

<servlet-mapping>
  <servlet-name>Faces Servlet</servlet-name>
  <url-pattern>*.jsf</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
Mohammod Hossain
  • 4,134
  • 2
  • 26
  • 37
  • I don't think that's correct. This is the extension for the actual file on disk. OP probably want the URL suffix, which you change via the url-pattern in the servlet-mapping in web.xml (or by omitting web.xml as *.jsf is the default in JSF 2.1). – Mike Braun Aug 25 '12 at 09:48
  • Forget the previous comment, comment was for another answer that said to change default_suffix only. In this case, the servlet-mapping is enough, no need to change default_suffix. – Mike Braun Aug 25 '12 at 09:51
  • Thenk you for your Answer which is probably correct regarding other sources. Sorry for delay - i was at Vacation, could I ask for one more help? When I use it and acces page.jsf (page.xhtml exist on server side) null pointer exeption is thrown, where could be the problem? There is web.xml: http://pastebin.com/3NqyYXSL and there is stack print http://pastebin.com/g76TgabF – Tomas Sep 16 '12 at 07:46
  • 1
    The context param is completely unnecessary. This piece of code originates from a JSF 1.x + Facelets 1.x application. – BalusC Sep 27 '12 at 12:01
-1
you can add this code in your web.xml, and you can run your pages ends with xhtml, jsf or faces
 <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>*.jsf</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.faces</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
  </servlet-mapping>