This article will provide an introduction to the Facelets framework with the assumption that the readers have a basic understanding on Java Server Pages. With the Introduction of JSF, the idea is to make JSP as the view technology for JSF. However the architecture of JSF and JSP are completely different and there were integration issues with the combination of JSF and JSP. With this in mind, Facelets was introduced which is another view definition framework similar to JSP. However, the architecture of the Facelets was designed with the complex JSF architecture and life-cycle in mind so that the component trees construction of Facelets can nicely mingle with JSF. Also in comparision with JSF, facelets can provide extending re-use of content code through templates.
Download Example Code for Facelets
Hello World Application
In this section, we will look into a starter application that will display the text Hello in the browser. The application will make the view as Facelets instead. We will provide explanation with the various aspects while going through the snippet code in the relevant section.
In the example application, the web application deployment descriptor is configured to look up for the file hello.jsp. The following is the code listing for the file hello.jsp. The page does a forward to the file hello.jsf. The extension of the forward file is ‘.jsf’ and in the application’s deployment descriptor (which we will be seeing in the next section), we will see such requests forwarded to the Faces Servlet.
<%@page contentType="text/html" pageEncoding="UTF-8"%> <jsp:forward page="hello.jsf"/>
The code listing for the facelets page is given below. Once we can see that the following page has the extension .xhtml. Later on we will see how to map this extension to a Facelets page. Also within the page we have included the namespace uri ‘http://java.sun.com/jsf/facelets’ so that we can refer to Facelets related tags in the page.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"> <body> <ui:composition template="/template.xhtml"> <ui:define name="heading"> Hello world application(Heading area) </ui:define> <ui:define name="body"> Hello World1! (Body area) </ui:define> </ui:composition> </body> </html>
In the above page, we have included the ui:composition and ui:define tags. The ui:composition along with the template attribute instructs that we want to use the page referenced in the attribute as the template page. The template page that we will look in the following section defines the section for the title content and the body content through ‘h1′ (heading) and ‘p’ (body) contents. The logical names given for the heading and the body content are ‘heading’ and ‘body’. Now back to the ‘hello.xhtml’, it is always possible to define or override the logical named sections in the template page. In our case, we have overridden the sections ‘heading’ and ‘body’ with some simple customized content through ui:define tags.
One could remember the usage of template.xhtml is the previous section, the content being giving in the following section. As discussed, this template page has provided named logical sections for the heading and the body area. It does this definition with the usage of ui:insert tags. Once this template page is defined, it is possible to override the named logical sections. For example, if the logical section ‘heading’ is not defined in the template-client page, i.e. the template page used by some client, in our case this file is hello.xhtml, then the content in the template.xhtml will be displayed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Facelets - Template Example</title> <link href="./css/default.css" rel="stylesheet" type="text/css" /> </head> <body> <h1> <ui:insert name="heading">Default Heading area to be overriden</ui:insert> </h1> <p> <ui:insert name="body">Default body area to be overriden</ui:insert> </p> </body> </html>
Web Application deployment Descriptor
The web application’s deployment descriptor file is given below. As you can see in the snippet code, the requests ending with ‘*.jsf’ are mapped to Faces Servlet. But till now we haven’t specified how Facelets is coming into the picture. We will see it shortly.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" 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_2_5.xsd"> <context-param> <param-name>com.sun.faces.verifyObjects</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>com.sun.faces.validateXml</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>javax.faces.DEFAULT_SUFFIX</param-name> <param-value>.xhtml</param-value> </context-param> <context-param> <param-name>facelets.DEVELOPMENT</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>facelets.SKIP_COMMENTS</param-name> <param-value>true</param-value> </context-param> <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> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file>hello.jsp</welcome-file> </welcome-file-list> </web-app>
Also, there are various parameters defined with respect to the Faces Servlet. Significant parameters being the development mode (represented through facelets.DEVELOPMENT) which when set to true instructs the framework that the application is still in development and any errors during page requests will be displayed in the browser.
The vendor specific application’s deployment descriptor is given below. It defines the context name of the application set to Facelets-Helo
1 2 3 4 5
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Servlet 2.5//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd"> <sun-web-app error-url=""> <context-root>/Facelets-Hello</context-root> </sun-web-app>
Faces Configuration file
The view handler for JSF is implemented through ViewHandler. To ensure that our application is using the View definition framework of Facelets, all we have to do is to replace the JSF version of View Handler with the Facelets view which happens to be ‘com.sun.facelets.FaceletViewHandler’ in the configuration file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<?xml version='1.0' encoding='UTF-8'?> <faces-config version="1.2" 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_1_2.xsd"> <application> <view-handler> com.sun.facelets.FaceletViewHandler </view-handler> </application> </faces-config>
Facelets – Hello Application.