The term Facelets is used to refer to the JavaServerTM Faces View Definition Framework, which is a page declaration language that was developed for use with JavaServer Faces technology. As of JavaServer Faces 2.0, Facelets is a part of JavaServer Faces specification and also the preferred presentation technology for building JavaServer Faces based applications.
JavaServer PagesTM (JSPTM) technology, previously used as the presentation technology for JavaServer Faces, does not support all of the new features available in JavaServer Faces 2.0. JSP is considered as a deprecated presentation technology for JavaServer Faces 2.0.
The following topics are addressed here:
Reuse of code and ease of development are important considerations for developers to adopt JavaServer Faces as the platform for large scale projects. By supporting these features, Facelets reduces the time and effort on development and deployment.
Facelets advantages include the following:
Support for code reuse through templating and composite components
Functional extensibility of components and other server-side objects through customization
Faster compilation time
Compile time EL validation
High performance rendering
Facelets is a powerful but lightweight page declaration language that is used to build JavaServer Faces views using HTML style templates and to build component trees.
Facelets features include the following:
Use of XHTML for creating web pages
Support for Facelets Tag libraries in addition to JavaServer Faces and JSTL tag libraries
Support for unified expression language
Templating for components and pages
Facelets views are usually created as XHTML pages. JavaServer Faces implementations support XHTML pages created in conformance with the XHTML Transitional DTD, as listed at http://www.w3.org/TR/xhtml1/#a_dtd_XHTML-1.0-Transitional.
By convention, web pages built with XHTML have an .xhtml extension.
JavaServer Faces technology supports different tag libraries to add components to a web page. To support the JavaServer Faces tag library mechanism, Facelets uses XML namespace declarations.
The following table Table 5–1 lists the tag libraries supported by Facelets.
Table 5–1 Tag Libraries Supported by Facelets
Tag Library |
URI |
Prefix |
Example |
Contents |
---|---|---|---|---|
JavaServer Faces Facelets Tag Library |
http://java.sun.com/jsf/facelets |
ui: |
ui:component ui:insert |
Tags for templating |
JavaServer Faces HTML Tag Library |
http://java.sun.com/jsf/html |
h: |
h:head h:body h:outputText h:inputText |
JavaServer Faces component tags for all UIComponents. |
JavaServer Faces Core Tag Library |
http://java.sun.com/jsf/core |
f: |
f:actionListener f:attribute |
Tags for JavaServer Faces custom actions that are independent of any particular RenderKit. |
JSTL Core Tag Library |
http://java.sun.com/jsp/jstl/core |
c: |
c:forEach c:catch |
JSTL 1.1 Core Tags |
JSTL Functions Tag Library |
http://java.sun.com/jsp/jstl/functions |
fn: |
fn:toUpperCase fn:toLowerCase |
JSTL 1.1 Functions Tags |
In addition, Facelets also supports tags for composite components for which you can declare custom prefixes. For more information on composite components, see Composite Components.
Based on the JavaServer Faces support for unified expression language (EL) syntax defined by JSP 2.1, Facelets uses EL expressions to reference properties and methods of backing beans. EL expressions can be used to bind component objects or values to managed-bean methods or managed-bean properties. For more information on using EL expressions, see Using the EL to Reference Backing Beans.
This section describes the general steps involved in developing a JavaServer Faces application.
Developing a simple JavaServer Faces application, using Facelets technology usually requires these tasks:
Developing the backing beans
Creating the pages using the component tags
Defining page navigation
Mapping the FacesServlet instance
Adding managed bean declarations
In the next section some of the above tasks are described in more detail.
The example used in this tutorial is the guessnumber application. The application presents you with a page that asks you to guess a number between 0 and 10, validates your input against a random number, and responds with another page that informs you, if you guessed the number correctly or incorrectly.
In a typical JavaServer Faces application each page in the application connects to a backing bean (a type of managed bean). The backing bean defines the methods and properties that are associated with the components.
The following managed bean class, UserNumberBean.java, generates a random number between 0 and 10:
package guessNumber; import java.util.Random; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; @ManagedBean @SessionScoped public class UserNumberBean { Integer randomInt = null; Integer userNumber = null; String response = null; private long maximum=10; private long minimum=0; public UserNumberBean() { Random randomGR = new Random(); randomInt = new Integer(randomGR.nextInt(10)); System.out.println("Duke's number: " + randomInt); } public void setUserNumber(Integer user_number) { userNumber = user_number; } public Integer getUserNumber() { return userNumber; } public String getResponse() { if ((userNumber != null) && (userNumber.compareTo(randomInt) == 0)) { return "Yay! You got it!"; } else { return "Sorry, " + userNumber + " is incorrect."; } } public long getMaximum() { return (this.maximum); } public void setMaximum(long maximum) { this.maximum = maximum; } public long getMinimum() { return (this.minimum); } public void setMinimum(long minimum) { this.minimum = minimum; } }
Note the use of the @ManagedBean annotation which registers the backing bean as a resource with JavaServer Faces implementation. The @SessionScoped annotation registers the bean scope as session.
Creating a page or view is the responsibility of a page author. This task involves adding components on the pages, wiring the components to backing bean values and properties, and registering converters, validators, or listeners onto the components.
For the example application, XHTML web pages serve as the front end. The first page of the example application is a page called greeting.xhtml. A closer look at various sections of this web page provides more information.
The first section of the web page declares the content type for the page, which is XHTML:
<?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">
The next section declares the XML namespace for the tag libraries that are used in the web page:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html">
The next section uses various tags to insert components into the web page:
<!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:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <h:head> <title>Facelets Guess Number Application</title> </h:head> <h:body> <h:form> <h:graphicImage value="#{resource['images:wave.med.gif']}"/> <h2> Hi, <p>My name is Duke. I am thinking of a number between <b> #{userNumberBean.minimum} and #{userNumberBean.maximum}. </b> Can you guess it ?</p> <h:inputText id="userNo" value="#{userNumberBean.userNumber}"> <f:validateLongRange minimum="#{userNumberBean.minimum}" maximum="#{userNumberBean.maximum}"/> </h:inputText> <h:commandButton id="submit" value="Submit" action="response.xhtml"/> <h:message showSummary="true" showDetail="false" style="color: red; font-family: 'New Century Schoolbook', serif; font-style: oblique; text-decoration: overline" id="errors1" for="userNo"/> </h2> </h:form> </h:body> </html>
Note the use of the Facelets HTML tags to add components, and the Facelets core tag to validate the user input. An inputText component accepts user input and sets the value of the backing bean property userNumber through the EL expression #{userNumberBean.userNumber}. The input value is validated for value range by the JavaServer Faces standard validator f:validateLongRange.
The image file wave.med.gif, is added to the page as a resource. For more details about the resources facility, see Resources.
The submit command button starts validation of the input data. Using implicit navigation, it redirects the client to another page response.xhtml, which shows the response to your input.
You can now create the second page, response.xhtml, with the following content:
<!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:h="http://java.sun.com/jsf/html"> <h:head> <title>Guess Number Facelets Application</title> </h:head> <h:body> <h:form> <h:graphicImage value="#{resource['images:wave.med.gif']}"/> <h2> <h:outputText id="result" value="#{userNumberBean.response}"/> </h2> <h:commandButton id="back" value="Back" action="greeting.xhtml"/> </h:form> </h:body> </html>
Configuring a JavaServer Faces application involves various configuration tasks which include adding managed-bean declarations, navigation rules and resources bundle declarations in the application configuration resource files such as faces-config.xml, and mapping the Faces Servlet in the web deployment descriptor file such as a web.xml file. Application configuration is an advanced topic covered in Java EE 6 Tutorial, Volume II: Advanced Topics.
If you are using an IDE such as NetBeans IDE, a web deployment descriptor is automatically created for you. In such IDE created web.xml files, change the default greeting page which is index.xhtml, to greeting.xhtml. Here is an example web.xml file:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.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-app_3_0.xsd"> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</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>/faces/*</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file>faces/greeting.xhtml</welcome-file> </welcome-file-list> </web-app>
Note the use of parameter PROJECT_STAGE. ProjectStage is a context parameter identifying the status of a JavaServer Faces application in the software lifecycle.
The stage of an application can affect the behavior of the application. For example, if the project stage is defined as Development, debugging information is automatically generated for the user. If not defined by the user, the default project stage is considered as Production. Project Stage is covered in more detail in Java EE 6 Tutorial, Volume II: Advanced Topics.
The example Facelets application described in this chapter can be built, packaged, and deployed using the Java EE 6 SDK with NetBeans IDE. For details on how to obtain this software and configure your environment to run the examples, see Chapter 2, Using the Tutorial Examples. The source code for this example is also available in the tut-install/examples/web/guessnumber directory.
To create the example Facelets project, use the following procedure.
In NetBeans IDE, from the File menu, choose New Project.
The New Project wizard opens.
In the wizard, select Java Web as the category and Web Application as the project type and click Next.
The New Web Application wizard opens.
In the Project Name field, type guessNumber, and click Next.
In the Server and Settings page, select Server as GlassFish v3 from the Server menu, select Java EE version as Java EE 6 Web from the Java EE version menu, and then click Next.
In the Frameworks page, select the JavaServer Faces checkbox and click Finish.
A new Project is created and is available in the Projects window. A default file, index.xhtml, is created and opened in the Editor.
Right-click the Project node, and select New->Java package.
In the Package Name field, type guessNumber and click Finish.
A new package is created and placed under Source Packages node of the Project.
Right-click the Source Packages node and select New->Java Class.
Type the name of the class file as UserNumberBean, select the name of package as guessNumber and click Finish.
A new Java class file is created and opened in the IDE.
Replace the content of the Java class file with the example code from the UserNumberBean.java file listed in Developing a Backing Bean, and save the file.
Create two new XHTML pages and name them greeting.xhtml and response.xhtml respectively:
Right-click the project node and choose New->Other.
The New File wizard opens.
Choose Category as Web and then File Type as XHTML and click Next.
Enter greeting.xhtml in the XHTML File name field and click Finish.
A new XHTML web page is created and placed under Web Pages node.
Repeat the above steps but enter the name of file as response.xhtml to create a second web page.
Edit the XHTML files and add Facelets content to them:
Replace the content of greeting.xhtml with the example greeting.xhtml code listed in Creating Facelets Views and save the file.
Similarly replace the content of response.xhtml with the example response.xhtml code and save the file.
Add Duke's image as part of the application by copying the wave.med.gif image file from the tutorial example and saving it as a resource.
Edit the web.xml file to modify the welcome page to greeting.html.
Right-click the Project Node and select Build from the menu, to compile and build the application.
Right-click the Project Node and select Deploy, to deploy the application to Sun GlassFishTM Enterprise Server v3.
Access the application by typing the following URL in the browser:
http://localhost:8080/guessNumber |
JavaServer Faces 2.0 provides the tools to implement user interfaces that are easy to extend and reuse. Templating is a useful feature available with Facelets that allows you to create a page that will act as the base or template for the other pages in a application. By using templates, you can reuse code and avoid recreating similarly constructed pages. Templating also helps in maintaining a standard look and feel in an application with a large number of pages.
The following table lists Facelets tags that are used for templating and their respective functionality:
Table 5–2 Facelets Templating Tags
Tag |
Function |
---|---|
ui:component |
Defines a component that is created and added to the component tree. |
ui:composition |
Defines a page composition that optionally uses a template. Content outside of this tag is ignored. |
ui:debug |
Defines a debug component that is created and added to the component tree. |
ui:define |
Defines content that is inserted into a page by a template |
ui:decorate |
Similar to composition tag but does not disregard content outside this tag. |
ui:fragment |
Similar to component tag but does not disregard content outside this tag. |
ui:include |
Encapsulate and reuse content for multiple pages. |
ui:insert |
Inserts content into a template. |
ui:param |
Used to pass parameters to an included file. |
ui:repeat |
Used as an alternative for loop tags such as c:forEach or h:dataTable. |
ui:remove |
Removes content from a page. |
For more information on Facelets templating tags, see the PDL athttp://java.sun.com/javaee/javaserverfaces/2.0/docs/pdldocs/facelets/index.html.
The Facelets tag library includes the main templating tag <ui:insert>. Atemplate page is created with this tag, it allows defining a default structure for a page. A template page can be reused as a template for other pages, usually referred to as a client pages.
Here is an example of a template saved as template.xhtml:
<!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"> <h:head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link href="./resources/css/default.css" rel="stylesheet" type="text/css" /> <link href="./resources/css/cssLayout.css" rel="stylesheet" type="text/css" /> <title>Facelets Template</title> </h:head> <h:body> <div id="top" class="top"> <ui:insert name="top">Top Section</ui:insert> </div> <div> <div id="left"> <ui:insert name="left">Left Section</ui:insert> </div> <div id="content" class="left_content"> <ui:insert name="content">Main Content</ui:insert> </div> </div> </h:body> </html>
The example page defines a HTML page that is divided into 3 sections, a top section, a left section and a main section. The sections have stylesheets associated with them. The same structure can be reused for the other pages of the application.
The client page invokes the template by using <ui:composition> tag. In the following example, a client page named templateclient.xhtml, invokes the template page from the preceding example named template.xhtml. A client page allows content to be inserted with the help of the <ui:define> tag.
<!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"> <h:body> <ui:composition template="./template.xhtml"> <ui:define name="top"> Welcome to Template Client Page </ui:define> <ui:define name="left"> <h:outputLabel value="You are in the Left Section"/> </ui:define> <ui:define name="content"> <h:graphicImage value="#{resource['images:wave.med.gif']}"/> <h:outputText value="You are in the Main Content Section"/> </ui:define> </ui:composition> </h:body> </html>
You can use the NetBeans IDE to create Facelets template and client pages. For more information on creating these pages, see http://netbeans.org/kb/docs/web/jsf20-intro.html.
The JavaServer Faces offers the concept of composite components with Facelets. A composite component can be considered a a special type of template that acts as a component.
Any component essentially is a piece of reusable code that is capable of a certain functionality. For example, an inputText component is capable of accepting user input. A component also has validators, converters, and listeners attached to it to perform certain defined actions.
A composite component is a component that consists of a collection of markups and other existing components. It is a reusable, user-created component that is capable of a customized, defined functionality and can have validators, converters and listeners attached to it like a any other JavaServer Faces component.
With Facelets, any XHTML page that is inserted with markups and other components, can be converted into a composite component. Using the resources facility, the composite component can be stored in a library that is available to the application from the defined resources location.
The following table lists the most commonly used composite tags and their functions:
Table 5–3 Composite Component Tags
Tag |
Function |
---|---|
composite:interface |
Declares the usage contract for a composite component. The composite component can be used as a single component whose feature set is the union of the features declared in the usage contract. |
composite:implementation |
Defines the implementation of the composite component. If a <composite:interface> element appears, there must be a corresponding <composite:implementation>. |
composite:attribute |
Declares an attribute that may be given to an instance of the composite component, in which this tag is declared. |
composite:insertChildren |
Any child components or template text within the composite component tag in the using page will be re-parented into the composite component at the point indicated by this tag's placement within the composite:implementation section. |
composite:valueHolder |
Declares that the composite component whose contract is declared by the composite:interface in which this element is nested exposes an implementation of ValueHolder suitable for use as the target of attached objects in the using page. |
composite:editableValueHolder |
Declares that the composite component whose contract is declared by the composite:interface in which this element is nested exposes an implementation of EditableValueHolder suitable for use as the target of attached objects in the using page. |
composite:actionSource |
Declares that the composite component whose contract is declared by the composite:interface in which this element is nested exposes an implementation of ActionSource2 suitable for use as the target of attached objects in the using page. |
For more information and a complete list of Facelets composite tags, see the PDL athttp://java.sun.com/javaee/javaserverfaces/2.0/docs/pdldocs/facelets/index.html.
The following example shows a composite component that accepts an email address as input:
<!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:composite="http://java.sun.com/jsf/composite" xmlns:h="http://java.sun.com/jsf/html"> <h:head> <title>This content will not be displayed </title> </h:head> <h:body> <composite:interface> <composite:attribute name="value" required="false"/> </composite:interface> <composite:implementation> <h:outputLabel value="Email id: "> </h:outputLabel> <h:inputText value="#{cc.attrs.value}"> </h:inputText> </composite:implementation> </h:body> </html>
Note the use of cc.attrs.value when defining the value of the inputText component. The word cc in JavaServer Faces is a reserved word for composite components. The #{cc.attrs.ATTRIBUTE_NAME} expression is used to access the attributes defined for the composite component's interface which in this case happens to be value.
The preceding example content is stored as a file named email.xhtml, in a folder named resources/emcomp under the application web root directory. This directory is considered a library by the JavaServer Faces, and a UIcomponent can be accessed from such library. For more information on resources, see Resources.
The web page that uses this composite component is generally called a using page. The using page includes a reference to the composite component, in the xml namespace declarations:
<!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:h="http://java.sun.com/jsf/html" xmlns:em="http://java.sun.com/jsf/composite/emcomp/"> <h:head> <title>Using a sample composite component</title> </h:head> <body> <h:form> <em:email value="Enter your email id" /> </h:form> </body> </html>
The local composite component library is defined in the xml namespace with the declaration xmlns:em="http://java.sun.com/jsf/composite/emcomp/". the component it self is accessed through the use of the tag em:email. The preceding example content can be stored as a web page named emuserpage.xhtml under web root directory. When compiled and deployed on a server it can be accessed with the following URL:
http://localhost:8080/<application_name>/faces/emuserpage.xhtml |
Resources refers to any software artifacts that the application requires for proper rendering. They include images, script files and any user-created component libraries. As of JavaServer Faces 2.0, resources must be collected in a standard location, which can be one of the following:
A resource packaged in the web application root must be in a subdirectory of a resources directory at the web application root: resources/<resource-identifier>.
A resource packaged in the web application's classpath must be in a subdirectory of the META-INF/resources directory within a web application: META-INF/resources/<resource-identifier>.
The JavaServer Faces runtime will look for the resources in the above listed locations, in that order.
Resource identifiers are unique strings that conform to the following format:
[localePrefix/][libraryName/][libraryVersion/]resource name[/resourceVersion]
Elements of the resource identifier in brackets ([]) are optional. This indicates that only a resource name is a required element, which is usually a file name.
Resources can be considered as a library location. Any artifacts, like a composite component or template that is stored under resources directory, becomes accessible to the other components of the application which can use them to create a resource instance.