Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Java Server Faces (JSF) Web-Applications: Tuning and Configuration

DZone's Guide to

Java Server Faces (JSF) Web-Applications: Tuning and Configuration

Learn how to increase the security and UI/UX of your Java-based web application using XML and the Java Server Faces framework.

· Java Zone ·
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

Introduction

Recently, and during helping many organizations in government, banking and educational domains developing Java web-based applications using Java Server Faces (JSF) technology, I have noticed that most developers and technical teams misconfigure different aspects of JSF applications, which dramatically affected the behavior, performance, and security of those applications.

In this article, I will present the required configurations and tuning to ensure the stability, security, and performance of JSF applications.

Note: For more information about building high-quality JSF applications, it is highly recommanded that you read “Java Server Faces in Real-life applications.”  article.

Web-Application (Servlets) Version

You can configure Java web applications (Servlets container) to use either version 3.0 or 3.1, which should be configured based on your web server version.
This can be done by:

  1. Creating web.xml in WEB-INF folder if it doesn't already exist.

  2. Ensure  that web-app tag contains the following configurations:

For servlet 3.0

<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">
</web-app>

For servlets 3.1

<?xml version="1.0" encoding="UTF-8"?>
<web-app
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">
</web-app>

JSF Version

To force JSF to use version 2.2 :

  1. Create a faces-config.xml file in the WEB-INF folder if doesn't already exist.
  2. Be sure that the faces-config tag is configured as follows:
<faces-config
      xmlns="http://xmlns.jcp.org/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
      version="2.2">
</faces-config>

View-Expired Exception

One of the issues that developers frequently face during development or testing is the ViewExpiredException which is caused by losing the state of the JSF view during the servlet container restarts. This issue can easily be solved by adding the following context parameter to WEB-INF/web.xml :

   <context-param>
          <param-name>com.sun.faces.enableRestoreView11Compatibility</param-name>
          <param-value>true</param-value>
   </context-param>

Time Zone

In JSF, the default time-zone is UTC time-zone, not the system time-zone, which will cause many issues, especially in the calendar, date and time components.
This can be solved by adding the following context parameter to WEB-INF/web.xml:

    <context-param>
            <param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name>
            <param-value>true</param-value>
    </context-param>

Development Mode

To force the page to reload and refresh the mode for all JSF views without the need to restart the server or redeploy the web application, add the following context parameters to the WEB-INF/web.xml:

   <context-param>
          <param-name>facelets.DEVELOPMENT</param-name>
          <param-value>true</param-value>
   </context-param>

   <context-param>
          <param-name>facelets.REFRESH_PERIOD</param-name>
          <param-value>0</param-value>
   </context-param>

Production Mode

In production mode, reloading the pages and JSF views in every request will dramatically and negatively affect the performance of the application. To increase the performance, in this case, the solution is view caching. To do so, change the development mode tags to be as follows in the WEB-INF/web.xml:

   <context-param>
          <param-name>facelets.DEVELOPMENT</param-name>
          <param-value>false</param-value>
   </context-param>

   <context-param>
          <param-name>facelets.REFRESH_PERIOD</param-name>
          <param-value>-1</param-value>
   </context-param>

JSF Tree and Components Caching

Another main issue that most JSF developers face is the overhead caused by the view components tree (JSF tree) processing during the JSF life cycle. However, most of the JSF tree components are do not need to be processed every time; for example, the dynamic header, footer and application scope menus will not change during the application scope. Also, the user level menu will be the same during the user session in most of the applications, and processing these components in the JSF tree doesn’t make sense, and can be avoided using OmniFaces cache components.

OmniFaces cache can be used as follows:

  1. Add the Omnifaces dependency to your pom.xml (assuming you use maven).
  2. Add xmlns to your HTML tag in the JSF view.
xmlns:of=http://omnifaces.org/ui

 3.  Encapsulate the block you want to cache inside the <of:cache> tag , for example:

<of:cache scope="session" reset="#{mb.resetCache}">
 ...
 ...
</of:cache>

This example will cache the encapsulated tags during the session. The second parameter will reset the cache for this object of the method, and resetCache() will return as true. Of course, you can cache the components in different scopes, such as the application's view scopes.

Ajax Exception, Debugging and Error-Pages

Another common issue is the handling exception during Ajax requests, where Faces's servlet behavior, in this case, is strangely just eating the exception.

To solve this issue:

  1. Add OmniFaces dependency to your maven project as mentioned in the previous section.
  2. Cause the exception thrown during the Ajax request to be handled the same way as a normal request by using the Omnifaces FullAjax handler, and by adding the following to WEB-INF/faces-config.xml file:
<factory>
<exception-handler-factory>org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory</exception-handler-factory>
</factory>

  3. Add the following section to WEB-INF/web.xml:

<error-page>
       <exception-type>com.sun.faces.context.FacesFileNotFoundException</exception-type>
       <location>/pages/error/file-not-found.xhtml</location>
</error-page>
<error-page>
<exception-type>java.lang.RuntimeException</exception-type>
       <location>/pages/error/bug.xhtml</location>
</error-page>
<error-page>
       <exception-type>java.lang.Throwable</exception-type>
       <location>/pages/error/error.xhtml</location>
</error-page>
<error-page>
  <error-code>404</error-code>
  <location>/pages/error/page-not-found.xhtml</location>
</error-page>

4. Create the error and exception handler pages in the /pages/error folder. These pages could include code like this (this code has been taken from Omni-faces website):

<ul>
<li>Date/time: #{of:formatDate(now, 'yyyy-MM-dd HH:mm:ss')}</li>
<li>User agent: #{header['user-agent']}</li>
<li>User IP: #{request.remoteAddr}</li>
<li>Request URI: #{requestScope['javax.servlet.error.request_uri']}</li>
<li>Ajax request: #{facesContext.partialViewContext.ajaxRequest ? 'Yes' : 'No'}</li>
<li>Status code: #{requestScope['javax.servlet.error.status_code']}</li>
<li>Exception type: #{requestScope['javax.servlet.error.exception_type']}</li>
<li>Exception message: #{requestScope['javax.servlet.error.message']}</li>
<li>Stack trace:
<pre>#{of:printStackTrace(requestScope['javax.servlet.error.exception'])}</pre>
</li>
</ul>

Conclusion

Java Server Faces (JSF) is the standard technology for building web applications in Java. However, during the development and deployment of JSF applications, there are many tuning and configurations that should be implemented to make the applications more secure, reliable, and efficient. In this article, we covered the required tunings and configurations that can be used as a unified reference for JSF developers.

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

Topics:
jsf ,java ee ,web dev ,web application development

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}