Basic Requirements of a JavaServer Faces Application

In addition to configuring your application, you must satisfy other requirements of JavaServer Faces applications, including properly packaging all the necessary files and providing a deployment descriptor. This section describes how to perform these administrative tasks.

JavaServer Faces applications must be compliant with the Servlet specification, version 2.3 (or later) and the JavaServer Pages specification, version 1.2 (or later). All applications compliant with these specifications are packaged in a WAR file, which must conform to specific requirements in order to execute across different containers. At a minimum, a WAR file for a JavaServer Faces application must contain the following:

The WAR file typically has this directory structure:

index.html
JSP pages
WEB-INF/
   web.xml
   faces-config.xml
   tag library descriptors (optional)
   classes/
      class files
     Properties files
   lib/
      JAR files 

The web.xml file (or deployment descriptor), the set of JAR files, and the set of application files must be contained in the WEB-INF directory of the WAR file. Usually, you will want to use the ant build tool to compile the classes. You package the necessary files into the WAR and deploy the WAR file.

The ant tool is included in the Application Server. You configure how the ant build tool builds your WAR file via a build.xml file. Each example in the tutorial has its own build file, to which you can refer when creating your own build file.

Configuring an Application with a Deployment Descriptor

Web applications are configured via elements contained in the web application deployment descriptor. The deployment descriptor for a JavaServer Faces application must specify certain configurations, which include the following:

The deployment descriptor can also specify other, optional configurations, including:

This section gives more details on these configurations.

Identifying the Servlet for Life Cycle Processing

One requirement of a JavaServer Faces application is that all requests to the application that reference previously saved JavaServer Faces components must go through FacesServlet. A FacesServlet instance manages the request processing life cycle for web applications and initializes the resources required by JavaServer Faces technology. To comply with this requirement, follow these steps.

  1. Include a servlet element in the deployment descriptor.
  2. Inside the servlet element, include a display-name element and set it to FacesServlet.
  3. Also inside the servlet element, add a servlet-name element and set it to FacesServlet.
  4. Add a third element, called servlet-class, inside the servlet element and set it to javax.faces.webapp.FacesServlet. This is the fully-qualified class name of the FacesServlet class.
  5. After the servlet element, add a servlet-mapping element.
  6. Inside the servlet-mapping element, add a servlet-name element and set it to FacesServlet. This must match the name identified by the servlet-name element described in step 3.
  7. Also inside the servlet-mapping element, add a url-pattern element and set it to *.faces. This path will be the path to FacesServlet. Users of the application will include this path in the URL when they access the application. For the guessNumber application, the path is /guess/*.

Before a JavaServer Faces application can launch the first JSP page, the web container must invoke the FacesServlet instance in order for the application life cycle process to start. The application life cycle is described in the section The Life Cycle of a JavaServer Faces Page (page 300).

To make sure that the FacesServlet instance is invoked, you provide a mapping to it using the Aliases tab, as described in steps 5 through 7 above.

The mapping to FacesServlet described in the foregoing steps uses a prefix mapping to identify a JSP page as having JavaServer Faces content. Because of this, the URL to the first JSP page of the application must include the mapping. There are two ways to accomplish this:

The second method allows users to start the application from the first JSP page, rather than start it from an HTML page. However, the second method requires users to identify the first JSP page. When you use the first method, users need only enter

http://localhost:8080/guessNumber 

You could define an extension mapping, such as *.faces, instead of the prefix mapping /guess/*. If a request comes to the server for a JSP page with a .faces extension, the container will send the request to the FacesServlet instance, which will expect a corresponding JSP page of the same name to exist containing the content. For example, if the request URL is http://localhost/bookstore6/bookstore.faces, FacesServlet will map it to the bookstore.jsp page.

Specifying a Path to an Application Configuration Resource File

As explained in Application Configuration Resource File, an application can have multiple application configuration resource files. If these files are not located in the directories that the implementation searches by default or the files are not named faces-config.xml, you need to specify paths to these files. To specify paths to the files in the deployment descriptor follow these steps:

  1. Add a context-param element to the deployment descriptor.
  2. Add a param-value element inside the context-param element and call it javax.faces.CONFIG_FILES.
  3. Add a param-value element inside the context-param element and give it the path to your configuration file. For example, the path to the guessNumber application's application configuration resource file is /WEB-INF/faces-config.xml
  4. Repeat steps 2 and 3 for each application configuration resource file that your application contains.

Specifying Where State Is Saved

When implementing the state-holder methods (described in Saving and Restoring State, page 435), you specify in your deployment descriptor where you want the state to be saved, either client or server. You do this by setting a context parameter in your deployment descriptor:

  1. Add a context-param element to the deployment descriptor.
  2. Add a param-name element inside the context-param element and give it the name javax.faces.STATE_SAVING_METHOD.
  3. Add a param-value element to the context-param element and give it the value client or server, depending on whether you want state saved in the client or the server.

If state is saved on the client, the state of the entire view is rendered to a hidden field on the page. The JavaServer Faces implementation saves the state on the client by default. Duke's Bookstore saves its state in the client.

Restricting the Number of Views in a Session

By default, a total of 15 top-level views are allowed to exist in a session. Likewise, a total of 15 logical views are also allowed in session. Logical views are subviews of a top-level view. For example, if you have a page that includes multiple frames then each frame is a logical view.

If you have a simple application then the default of 15 views or 15 logical views might be too large. In this case, you should consider reducing the allowable number of views and logical views to conserve memory. Conversely, a more complex application might require more than 15 views or logical views to be saved in a session.

To change the number of views allowed in a session, do the following:

  1. In the deployment descriptor, add a context-param element.
  2. Inside the context-param element, add a param-name element and give it the name com.sun.faces.NUMBER_OF_VIEWS_IN_SESSION.
  3. Inside the context-param element, add a param-value element and give it the number of views that you want allowed in the session.

To change the number of logical views allowed for each root view in a session, do the following:

  1. In the deployment descriptor, add a context-param element.
  2. Inside the context-param element, add a param-name element and give it the name com.sun.faces.NUMBER_OF_VIEWS_IN_LOGICAL_VIEWS_IN_SESSION.
  3. Inside the context-param element, add a param-value element and give it the number of logical views that you want allowed for each root view in the session.

Encrypting Client State

When you are choosing to save state on the client, you are essentially saying that you want state to be sent over the wire and saved on the client in a hidden field. Clearly, this opens the door to potential tampering with the state information. To prevent this from happening, you can specify that the state must be encrypted before it is transmitted to the client by doing the following:

  1. Add an env-entry element to your deployment descriptor.
  2. Add an env-entry-name element to the env-entry element and give it the name com.sun.faces.ClientStateSavingPassword.
  3. Add an env-entry-value element to the env-entry element, and give it your password. The password that you provide is used to generate keys and ciphers for encryption.
  4. Add an env-entry-type element and give it the type of your password, which must be java.lang.String.

If your deployment descriptor does not contain this environment entry then no encryption of client-side state will occur.

Compressing Client State

If you have chosen to save state in the client, you can reduce the number of bytes sent to the client by compressing it before it is encoded and written to a hidden field. To compress client state, you need to do the following:

  1. In the deployment descriptor, add a context-param element.
  2. Add a param-name element inside the context-param element and give it the name com.sun.faces.COMPRESS_STATE.
  3. Add a param-value element to the context-param element and give it the value true. The default value is false.

Restricting Access to JavaServer Faces Components

In addition to identifying the FacesServlet instance and providing a mapping to it, you should also ensure that all applications use FacesServlet to process JavaServer Faces components. You do this by setting a security constraint with a security-constraint element. Inside the security-constraint element in the deployment descriptor, add the following:

  1. Add a display-name element to identify the name of the constraint.
  2. Add a web-resource-collection element.
  3. Inside the web-resource-collection element, add a web-resource-name element that identifies the purpose of the collection.
  4. Add a url-pattern element inside the web-resource-collection element and enter the path to a JSP page to which you want to restrict access, such as /response.jsp.
  5. Continue to add URL patterns for all the JSP pages to which you want to restrict access.

Turning On Validation of XML Files

Your application contains one or more application configuration resource files written in XML. You can force the JavaServer Faces implementation to validate the XML of these files by setting the validateXML flag to true:

  1. Add a context-param element to the deployment descriptor.
  2. Add a param-name element inside the context-param element and give it the name com.sun.faces.validateXml.
  3. Add a param-value element to the context-param element and give it the value true. The default value is false.

Verifying Custom Objects

If your application includes custom objects, such as custom components, converters, validators, and renderers, you can verify when the application starts that they can be created. To do this, you set the verifyObjects flag to true:

  1. Add a context-param element to the deployment descriptor.
  2. Add a param-name element inside the context-param element and give it the name com.sun.faces.verifyObjects.
  3. Add a param-value element to the context-param element and give it the value true. The default value is false.

Normally, this flag should be set to false during development because it takes extra time to check the objects.

Including the Required JAR Files

JavaServer Faces applications require several JAR files to run properly. These JAR files are as follows:

The jsf-api.jar and the jsf-impl.jar files are located in <JavaEE_HOME>/lib. The jstl.jar file is bundled in appserv-jstl.jar. The other JAR files are bundled in the appserv-rt.jar, also located in <JavaEE_HOME>/lib/.

When packaging and deploying your JavaServer Faces application, you do not need to explicitly package any of the JAR files.

Including the Classes, Pages, and Other Resources

When packaging web applications using the included build scripts, you'll notice that the scripts package resources as described here:

When packaging your own applications, you can use the build scripts included with the tutorial examples and modify them to fit your situation. However, we recommend that you continue to package your WAR files as described in this section because this technique complies with commonly-accepted practice for packaging web applications.