Wednesday, November 26, 2008

Integrating Spring Webflow to MyFaces

After working a couple of months developing a JSF based web application , I finally reached the point where I MUST integrate Spring to the project. The main reason is because I need the (conversation, flow and flash) scopes available in the Web Flow module.

JSF is a great MVC framework but up to this point it comes short of the tools I need, and SWF jumps in as a great complement to provide a solution to my current problem, but we all know that the Java world is huge and there are other frameworks with a similar goal to SWF, and for sure the biggest competitor is Seam.

The popularity of Seam has been growing a lot in the last months, and the fact that JBoss is on top of the work to create the Web Beans specification (JSR 299) and that Seam will be the base implementation, makes it a solid option, besides the community feedback has been very good and of course the integration with Richfaces is quite simple.

In this entry I will integrate Spring Webflow to MyFaces, and on the next one I will try to integrate MyFaces and Spring with Seam to get the best of both worlds.

The first step is to add the required Spring libraries, in my case I am using Maven so I added the repositories to my POM.xml file and declared the dependencies:

<repositories>
<repository>
<id>com.springsource.repository.bundles.release</id>
<name>
SpringSource Enterprise Bundle Repository - SpringSource
Releases
</name>
<url>
http://repository.springsource.com/maven/bundles/release
</url>
</repository>
<repository>
<id>com.springsource.repository.bundles.external</id>
<name>
SpringSource Enterprise Bundle Repository - External
Releases
</name>
<url>
http://repository.springsource.com/maven/bundles/external
</url>
</repository>
</repositories>

<!-- Spring webflow dependency -->
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>org.springframework.binding</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>org.springframework.js</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>org.springframework.webflow</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>org.springframework.faces</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
</dependencies>


Next step is to modify your faces-config.xml to include the Spring variable resolver, it will allow to use EL binding in the application and it will look for values stored in the different scopes :

<application>
<!-- Facelets configuration -->
<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
<message-bundle>resources/messages</message-bundle>
<!-- Spring integration -->
<application>
<variable-resolver>org.springframework.web.jsf.SpringBeanVariableResolver</variable-resolver>
</application>


Now it's time to modify the web.xml file. A context parameter named "contextConfigLocation" will include the location of the spring configuration files, in our case we'll specify the webflow-config.xml, this file will contain the flows controlled by SWF.

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:resources/services-config.xml
/WEB-INF/webflow-config.xml
</param-value>
</context-param>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>


Already at this point the application can be used again, and a simple reference to a bean can be declared at the webflow-config.xml like this:


<bean class="app.sample.beans.biz.UserSessionBean" scope="session" name="UserSessionBean"/>


Then we can access this bean from the jspx with the following EL:

#{UserSessionBean.loadSite}

That's it! a quick Spring integration to a MyFaces web application now you can start creating your flows and including your beans.
blog comments powered by Disqus