Partial Facelets Adoption
December 11, 2006
So you have committed to JSF, but have already completed a large majority of your project before hearing about Facelets (or perhaps before it was even released). Since Facelets promises to solve the painful mismatch between JSF and JSP, you would like to take advantage of it. "But how?" you ask, because it is certainly not reasonable to think that you are going to rewrite all of your JSP files over night. Thanks to a lesser known option in Facelets, facelets.VIEW_MAPPINGS, it is possible to partially adopt Facelets by migrating only handful of pages at a time. The facelets.VIEW_MAPPING option tells Facelets which page requests the FaceletViewHandler should process. All the non-matching page requests will be passed up the chain to the default JSF view handler (JspViewHandler).
Assuming you have already gone through the required steps to setup Facelets, the only additional step is to define the pages that you would like Facelets to handle. However, before doing this step, it is necessary to revert the configuration of the javax.faces.DEFAULT_SUFFIX option back to its default value (.jsp), rather than the value that the Facelets documentation recommends (.xhtml). Since Facelets will not handle all requests, the default suffix must be appropriate for the default JSF view handler to interpret.
<context-param> <param-name>javax.faces.DEFAULT_SUFFIX</param-name> <param-value>.jsp</param-value> <!-- .jspx for XML syntax --> </context-param>
The list of pages that Facelets will handle is configured using the facelets.VIEW_MAPPING option in web.xml. The mappings are specified as a semicolon (;) delimitted list of resources. The resources can either be a file extension (such as *.xhtml) or a resource prefix (followed by an asterisk). The resource prefix style allows for matching either a subset of pages (such as /user/*) or just a single page (such as /login.jsp*). Because of the way that Facelets does prefix matching, it is necessary to include the trailing asterisk, even when matching against a single page.
Let's assume for a moment, that you are creating a new module for managing users. All the pages are placed in the "/user/" folder at the root of the web context. In that folder we may have pages such as "list.jsp", "detail.jsp", "edit.jsp" and so on. To configure Facelets to process only the pages in this folder and the login page (/login.jsp), while allowing the default JSF view handler to deal with any other page in the web application, you will need to add the following context-param definition to your web.xml file:
<context-param> <param-name>facelets.VIEW_MAPPINGS</param-name> <param-value>/login.jsp*;/user/*</param-value> </context-param>
This first example assumes that the same file extension is being used for both Facelets views and non-Facelets views. Another way to integrate Facelets is to use a different file extension (such as .xhtml) than what is used by the non-Facelets views. That way, it is easy to distinguish which files are handled by Facelets, and which ones are not. The configuration for that setup is a bit simpler.
<context-param> <param-name>facelets.VIEW_MAPPINGS</param-name> <param-value>*.xhtml</param-value> </context-param>
Of course, it is also possible to use a combination of the two approaches. It depends on how you would like to name your pages.
Now you are ready to take the plunge into Facelets without having to burn the midnight oil in order to migrate the entire application at once! And believe me, once you start using Facelets, you will want to thank somebody.