© Copyright 2015

Java Professionals

All rights reserved.

Technologies :

You Are Here: Home >> Articles >> Benefits of Using JSF With Spring

What are The Benefits of Using JSF With Spring

When you use JSF framework for java development, it makes the UI more effective. You can integrate the framework with other web application frameworks available in the technology world today. Integration of JSF with Spring web app framework is simpler to perform. In this article, you will learn major benefits of integrating JSF applications with Spring web flow applications. You will also learn how to configure web.xml with JSF.

To make effective UI, JSF is one of good framworks to integrate with web application. Most common web application framework Spring, provides a JSF integration in simple manner. It lets one use the JSF UI Component with Spring MVC and Spring Web Flow controllers. JSF version 2.0 or above is suitable to integrate with Spring Web Flow version 2.4. Both Sun Mojarra and Apache MyFaces runtime environments are supported by Spring Web Flow version 2.4.

There are few benefitial areas of Integration of JSF applications with Spring Web Flow applications which are listed below:

  • Managed bean facility
  • Scope management
  • Event handling
  • Navigation
  • Modularization and packaging of views
  • Cleaner URLs
  • Model-level validation

These features noticebly reduce the amount of configuration required in faces-config.xml file. By using this scenerio view and controller layers cab be separated with better modularization of application functionals.

To configure JSF in Spring web applicatioin a configuration xml file called 'faces-config.xml' is required, which contains basic <faces-config> tag.

This tag basically contains following data.


<?xml version='1.0' encoding='UTF-8'?>
<faces-config 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_2_0.xsd"
version="2.0">
</faces-config>

There is a class clled DelegatingVariableResolver  in spring to integrate JSF with Spring together in logical manner.  To integrate Spring Dependency Injection (IOC) feature in JSF Add a variable-resolver entry in faces-config.xml to point to spring class DelegatingVariableResolver.

<faces-config>
   <application>
   <variable-resolver>
      org.springframework.web.jsf.DelegatingVariableResolver
   </variable-resolver>
   ...
</faces-config>

DelegatingVariableResolver  delegates value lookups to the JSF default resolver and after that to WebApplicationContext of Spring. This DelegatingVariableResolver allows to easily inject dependencies of spring base into JSF-managed beans.

<faces-config>
   ...
   <managed-bean>
      <managed-bean-name>Bean Name</managed-bean-name>
      <managed-bean-class>Path to Bean class</managed-bean-class>
      <managed-bean-scope>request</managed-bean-scope>
      <managed-property>
         <property-name>Property name</property-name>
         <value>#{value}</value>
      </managed-property>
   </managed-bean>
</faces-config>

Configuring web.xml

As one knows who is familiar with spring, requests flows to the Dispatcher-Servlet  configured in the web.xml file. In this example ,all URLs  are mapped to the servlet which begin with /spring/. The servlet needs to be configured. There is  init-param in the servlet to pass the contextConfigLocation. This is, where the Spring configuration for web application is located.

<servlet>
<servlet-name>Spring Web Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/Application-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>Spring Web Dispatcher Servlet</servlet-name>
<url-pattern>/spring/*</url-pattern>
</servlet-mapping>

To bootstrap JSF correctly, the web.xml must contain FacesServlet configured in it same as it normally would, even though one generally won't need to route requests by it at all when using JSF and Spring Web Flow in integration.

<!--  here  the JSF implementation can be initialized,  NOT used at runtime -->
<servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
</servlet>

<!-- Just here  the JSF implementation can be initialized -->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>

While using Facelets instead of JSP typically requires following tag in web.xml:

<!-- Use JSF view templates saved as *.html, for use with Facelets -->
<context-param>
        <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
        <param-value>.html</param-value>
</context-param>

ContextLoaderListener and RequestContextListener  listener need to add which are provided by spring framework in web.xml file.

<web-app>
   ...
   <!-- Add Support for Spring -->
   <listener>
      <listener-class>
         org.springframework.web.context.ContextLoaderListener
      </listener-class>
   </listener>
   <listener>
      <listener-class>
         org.springframework.web.context.request.RequestContextListener
      </listener-class>
   </listener>
   ...
</web-app>

Configuring Web Flow for use with JSF
This area is about configuration of  Web Flow with JSF.  It supports both Java and XML style configuration. The below code snippets a sample configuration in XML file for both Web Flow and JSF as well.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:webflow="http://www.springframework.org/schema/webflow-config"
        xmlns:faces="http://www.springframework.org/schema/faces"
        si:schemaLocation="
                http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                http://www.springframework.org/schema/webflow-config
                http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.4.xsd
                http://www.springframework.org/schema/faces
                http://www.springframework.org/schema/faces/spring-faces-2.4.xsd">

        <!-- Executes flows: the central entry point into the Spring Web Flow system-->
<webflow:flow-executor id="flowExecutor">
<webflow:flow-execution-listeners>
<webflow:listener ref="facesContextListener"/>
</webflow:flow-execution-listeners>
</webflow:flow-executor>

        <!-- The registry of executable flow definitions -->
<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices" base-path="/WEB-INF/*">
<webflow:flow-location-pattern value="**/*-flow.xml" />
</webflow:flow-registry>

        <!-- Integration of the Spring Web Flow with JSF configuration -->
<faces:flow-builder-services id="flowBuilderServices" />

        <!-- A listener maintain one FacesContext instance per Web Flow request. -->
<bean id="facesContextListener"
class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener" />

</beans>

The installation of a  FlowFacesContextLifecycle - Listener that manages a single FacesContext for the duration of Web Flow request is an important thing  and one another main poin is the use of the flow-builder-services element from the faces custom namespace to configure rendering for a JSF environment.

In a JSF environment one must need this Spring MVC related configuration:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns:faces="http://www.springframework.org/schema/faces"
                 xsi:schemaLocation="
                         http://www.springframework.org/schema/beans
                         http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                         http://www.springframework.org/schema/faces
                         http://www.springframework.org/schema/faces/spring-faces-2.4.xsd">

        <faces:resources />

        <bean class="org.springframework.faces.webflow.JsfFlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor" />
</bean>

</beans>

The resource requests of JSF are delegates by JSF resource API's custom namespace element. The FlowHandler-Adapter generally used with Web Flow is replaced by the JsfFlowHandlerAdapter. This adapter doesn't initialize with SpringJavaSciprtAjaxHandler, but it initilizeswith a JsfAjax-Handler itself.  AbstractFacesFlowConfiguration base class automatically registers JsfResource-RequestHandler , while using Java config so one has nothing to do further.                    

You need to implement the code shared in this article to your java development project for integrating JSF with spring. Don’t forget to share your experience with experts. In case of doubt, the team of professionals is here to help you and explain the facts you may need to know for better development practices.