SourceForge.net Logo

Package org.springframework.web.jsf

Support classes for the integration of JSF as Spring web MVC framework.

See:
          Description

Class Summary
FacesBeanDefinition RootBeanDefinition for beans defined in a JSF context.
FacesConfigXmlBeanDefinitionParser Faces implementation of the XmlBeanDefinitionParser interface.
FacesConfigXmlBeanDefinitionParser.FacesHierarchicalMessageSource JSF implementation of a HierarchicalMessageSource.
RequestHandledFilter Filter used to publish RequestHandledEvents to Spring's event queue.
SpringBeanFactory Wraps and enables JSF specific scope definition and management for a bean declared in the Spring context.
VariableResolverImpl VariableResolver implementation that builds up a WebApplicationContext using the inner class VariableResolverImpl.FacesWebApplicationContext based on the typical faces configuration files: /WEB-INF/faces-config.xml /META-INF/faces-config.xml Context initialization parameter FacesServlet.CONFIG_FILES_ATTR for a comma delimited list of context relative resource path.
 

Package org.springframework.web.jsf Description

Support classes for the integration of JSF as Spring web MVC framework.

Features

The main goal of this package is to provide code to integrate the two frameworks as transparently as possible:

JSF configuration integration

This package builds a WebApplicationContext based on your defined faces configuration files (e.g. /WEB-INF/faces-config.xml) maybe as a child of an ApplicationContext according to the "spring-beans" DTD (e.g. defined in /WEB-INF/applicationContext.xml). Since the WebApplicationContext according to the "faces-config" DTD is full featured, the following is enabled automatically:

Access beans managed by Spring from JSF programmatically

Since there is a hierarchy between the FacesWebApplicationContext according to the "faces-config" DTD and the ApplicationContext according to the "spring-beans" DTD your JSF managed backing beans could easily implement the ApplicationContextAware interface and access beans via the getBean method no matter if they are defined in the FacesWebApplicationContext (e.g. "faces-config.xml") or in the parent ApplicationContext (e.g. "applicationContext.xml").

Access beans managed by Spring from JSF via JSF EL

You can access beans using JSF EL not matter if the bean you refer to is managed by JSF or by Spring. The two bean contexts are merged at access time:

Usage

You usually set up your web application as you would do with any other JSF web application. The following sample configuration files show you how to enable the above mentioned features.

First, web.xml configuration:

WEB-INF/web.xml
<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC
  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
    <!--
        The filter used to publish RequestHandledEvent to Spring.
        Map it to whatever url pattern Spring should be notified
        of handled requests.
    -->
    <filter>
        <filter-name>RequestHandled</filter-name>
        <filter-class>org.springframework.web.jsf.RequestHandledFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>RequestHandled</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--
        The declaration of your FacesServlet.
        Map it to whatever url pattern you like.
    -->
    <servlet>
        <servlet-name>FacesServlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>FacesServlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
</web-app>

A web.xml configuration with net.sourceforge.myfaces JSF-implementation (with the use of the original MyFaces-VariableResolver):

WEB-INF/web.xml
<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC
  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
    <!--
        The declaration of the original MyFaces VariableResolver.
    -->
    <context-param>
        <param-name>org.springframework.web.jsf.VARIABLE_RESOLVER_CLASS</param-name>
        <param-value>net.sourceforge.myfaces.el.VariableResolverImpl</param-value>
    </context-param>
    
    <!--
        The filter used to publish RequestHandledEvent to Spring.
        Map it to whatever url pattern Spring should be notified
        of handled requests.
    -->
    <filter>
        <filter-name>RequestHandled</filter-name>
        <filter-class>org.springframework.web.jsf.RequestHandledFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>RequestHandled</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--
        The declaration of MyFaces startup-listener.
    -->
    <listener>
        <listener-class>net.sourceforge.myfaces.webapp.StartupServletContextListener</listener-class>
    </listener>

    <!--
        The declaration of your FacesServlet.
        Map it to whatever url pattern you like.
    -->
    <servlet>
        <servlet-name>FacesServlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>FacesServlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
</web-app>

A web.xml configuration with net.sourceforge.myfaces JSF-implementation (with the use of the internal spring-based VariableResolver - which enables a few features not supported by MyFaces, e.g. list-entries, map-entries...):

WEB-INF/web.xml
<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC
  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
    <!--
        The filter used to publish RequestHandledEvent to Spring.
        Map it to whatever url pattern Spring should be notified
        of handled requests.
    -->
    <filter>
        <filter-name>RequestHandled</filter-name>
        <filter-class>org.springframework.web.jsf.RequestHandledFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>RequestHandled</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--
        The declaration of MyFaces startup-listener.
    -->
    <listener>
        <listener-class>net.sourceforge.myfaces.webapp.StartupServletContextListener</listener-class>
    </listener>

    <!--
        The declaration of your FacesServlet.
        Map it to whatever url pattern you like.
    -->
    <servlet>
        <servlet-name>FacesServlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>FacesServlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
</web-app>

Second, you have to use the VariableResolver provided by this package which enables the above mentioned bean access features.

WEB-INF/faces-config.xml
<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC
  "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
  "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">

<faces-config>
    <!--
        Enable the VariableResolver provided by this package.
    -->
    <application>
        <variable-resolver>org.springframework.web.jsf.VariableResolverImpl</variable-resolver>
    </application>
</faces-config>

Example

In this example, we just use two beans:

WEB-INF/faces-config.xml (partial)
<!-- a purely JSF managed bean -->
<managed-bean>
    <managed-bean-name>jsfBean</managed-bean-name>
    <managed-bean-class>example.NameBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
        <property-name>name</property-name>
    </managed-property>
</managed-bean>

<!-- a SpringBeanFactory used to define the scope of a Spring managed bean -->
<managed-bean>
    <managed-bean-name>scopedAccessSpringBean</managed-bean-name>
    <managed-bean-class>org.springframework.web.jsf.SpringBeanFactory</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

<!-- a purely JSF managed bean that holds a reference to a Spring managed bean -->
<managed-bean>
    <managed-bean-name>referencingBean</managed-bean-name>
    <managed-bean-class>example.ReferencingBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
        <property-name>referencedBean</property-name>
        <value>#{managedPropertyAccessSpringBean}</value>
    </managed-property>
</managed-bean>

WEB-INF/applicationContext.xml (partial)
<!-- a purely Spring managed bean -->
<bean id="directAccessSpringBean" class="example.NameBean"/>

<!-- a Spring managed bean supplied with a scope within JSF -->
<bean id="scopedAccessSpringBean" class="example.NameBean" singleton="false"/>

<!--
    a purely Spring managed bean being referenced by a JSF managed bean
    (but which of course can be accessed directly as well)
->
<bean id="managedPropertyAccessSpringBean" class="example.NameBean" singleton="false"/>

test.jsp
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<html>
    <head><title>test</title></head>
    <body bgcolor="white">
        <f:view>
            <h:messages/>
            <h:form>
                purely JSF managed bean:
                <h:inputText value="#{jsfBean.name}"
                             valueChangeListener="#{jsfBean.valueChanged}"/>
                <h:commandButton value="action"
                                 actionListener="#{jsfBean.action}"/>
                <br/>
                purely Spring managed bean:
                <h:inputText value="#{directAccessSpringBean.name}"
                             valueChangeListener="#{directAccessSpringBean.valueChanged}"/>
                <h:commandButton value="action"
                                 actionListener="#{directAccessSpringBean.action}"/>
                <br/>
                scoped Spring managed bean:
                <h:inputText value="#{scopedAccessSpringBean.name}"
                             valueChangeListener="#{scopedAccessSpringBean.valueChanged}"/>
                <h:commandButton value="action"
                                 actionListener="#{scopedAccessSpringBeanaction}"/>
                <br/>
                referenced Spring managed bean:
                <h:inputText value="#{referencingBean.referencedBean.name}"
                             valueChangeListener="#{referencingBean.referencedBean.valueChanged}"/>
                <h:commandButton value="action"
                                 actionListener="#{referencingBean.referencedBean.action}"/>
                <br/>
                <h:commandButton id="submit" action="save" value="save"/>
            </h:form>
        </f:view>
    </body>
</html>


SourceForge.net Logo