Sunday, April 22, 2012

How to integrate JSF2.0 with Spring 3.0 Framework

Steps:

1. Create the Maven Project "JSF" with
groupId: com.jsf.app
artifactId: jsf
package: war
and add following dependencies in pom.xml

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
      <modelVersion>4.0.0</modelVersion>  
      <groupId>com.jsf.app</groupId>  
      <artifactId>jsf</artifactId>  
      <version>0.0.1-SNAPSHOT</version>  
      <packaging>war</packaging>  
      <name>jsf</name>  
      <url>http://maven.apache.org</url>  
      <properties>  
           <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
           <org.springframework.bom.version>3.1.0.RELEASE</org.springframework.bom.version>  
      </properties>  
      <dependencies>  
           <dependency>  
                <groupId>junit</groupId>  
                <artifactId>junit</artifactId>  
                <version>3.8.1</version>  
                <scope>test</scope>  
           </dependency>  
           <!-- Logging Dependencies -->            
           <dependency>  
                <groupId>log4j</groupId>  
                <artifactId>log4j</artifactId>  
                <version>1.2.14</version>  
           </dependency>  
           <!-- http://download.java.net/maven/2 -->  
           <dependency>  
                <groupId>com.sun.faces</groupId>  
                <artifactId>jsf-api</artifactId>  
                <version>2.1.0-b03</version>  
           </dependency>  
           <dependency>  
                <groupId>com.sun.faces</groupId>  
                <artifactId>jsf-impl</artifactId>  
                <version>2.1.0-b03</version>  
           </dependency>  
           <!-- http://repo1.maven.org/maven -->  
           <dependency>  
                <groupId>javax.servlet</groupId>  
                <artifactId>jstl</artifactId>  
                <version>1.2</version>  
           </dependency>  
           <dependency>  
                <groupId>javax.servlet</groupId>  
                <artifactId>servlet-api</artifactId>  
                <version>2.5</version>  
           </dependency>  
           <dependency>  
                <groupId>javax.servlet.jsp</groupId>  
                <artifactId>jsp-api</artifactId>  
                <version>2.1</version>  
           </dependency>  
           <dependency>  
                <groupId>com.sun.el</groupId>  
                <artifactId>el-ri</artifactId>  
                <version>1.0</version>  
           </dependency>  
           <!-- Spring Related Dependency -->       
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-core</artifactId>  
                <version>${org.springframework.bom.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-web</artifactId>  
                <version>${org.springframework.bom.version}</version>  
           </dependency>  
      </dependencies>  
 </project>  

2. Create the directory structure like:
jsf
-src
--main
---java
-----com
-------jsf
--------app
----------managedbean
-------------UserBean.java
----------service
-------------UserService.java
-------------impl
---------------UserServiceImpl.java
---resources
----applicationContext.xml
----log4j.xml
----messages.properties
---webapp
-----pages
-------jsfspring.xhtml
-----WEB-INF
--------faces-config.xml
--------web.xml
--test
--pom.xml

3. In web.xml file add these settings.
 <?xml version="1.0" encoding="UTF-8"?>  
 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
      xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
      http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
      id="WebApp_ID" version="2.5">  
      <display-name>JavaServerFaces&Spring</display-name>  
      <listener>  
           <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
      </listener>  
      <listener>  
           <listener-class>  
                org.springframework.web.context.request.RequestContextListener</listener-class>  
      </listener>  
      <listener>  
           <listener-class>com.sun.faces.config.ConfigureListener</listener-class>  
      </listener>  
      <context-param>  
           <param-name>javax.faces.PROJECT_STAGE</param-name>  
           <param-value>Development</param-value>  
      </context-param>  
      <context-param>  
           <param-name>contextConfigLocation</param-name>  
           <param-value>classpath:/applicationContext.xml</param-value>  
      </context-param>  
      <context-param>  
           <param-name>javax.faces.CONFIG-FILES</param-name>  
           <param-value>WEB-INF/faces-config.xml</param-value>  
      </context-param>  
      <context-param>  
           <param-name>com.sun.faces.expressionFactory</param-name>  
           <param-value>com.sun.el.ExpressionFactoryImpl</param-value>  
      </context-param>  
      <servlet>  
           <servlet-name>Faces Servlet</servlet-name>  
           <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>  
           <load-on-startup>1</load-on-startup>  
      </servlet>  
      <servlet-mapping>  
           <servlet-name>Faces Servlet</servlet-name>  
           <url-pattern>/faces/*</url-pattern>  
      </servlet-mapping>  
      <servlet-mapping>  
           <servlet-name>Faces Servlet</servlet-name>  
           <url-pattern>*.jsf</url-pattern>  
      </servlet-mapping>  
      <servlet-mapping>  
           <servlet-name>Faces Servlet</servlet-name>  
           <url-pattern>*.faces</url-pattern>  
      </servlet-mapping>  
      <servlet-mapping>  
           <servlet-name>Faces Servlet</servlet-name>  
           <url-pattern>*.xhtml</url-pattern>  
      </servlet-mapping>  
      <welcome-file-list>  
           <welcome-file>pages/jsfspring.xhtml</welcome-file>  
      </welcome-file-list>  
 </web-app>  

4.Create new JSF bean name as UserBean as shown below in com.jsf.app.managedbean package

 package com.jsf.app.managedbean;  
 import java.util.logging.Logger;  
 import org.springframework.beans.factory.annotation.Autowired;  
 import org.springframework.beans.factory.annotation.Qualifier;  
 import org.springframework.stereotype.Component;  
 import com.jsf.app.service.UserService;  
 @Component("userBean") 
 @Scope("session") 
 public class UserBean {  
      private static final Logger logger = Logger.getLogger(UserBean.class  
                .getName());  
      @Autowired  
      @Qualifier("userService")  
      public UserService userService;  
      public String getPrintMsgFromSpring() {  
           logger.info("Invoking UserService");  
           return userService.getMessage();  
      }  
 }  

5. Next create Spring Interface and Implementation in com.jsf.app.service and com.jsf.app.service.impl package respectively:
 package com.jsf.app.service;  
 public interface UserService {  
      public String getMessage();  
 }  


 package com.jsf.app.service.impl;  
 import org.springframework.stereotype.Service;  
 import com.jsf.app.service.UserService;  
 @Service("userService")  
 public class UserServiceImpl implements UserService {  
      private String name = "Voila!";  
      public String getName() {  
           return name;  
      }  
      public void setName(String name) {  
           this.name = name;  
      }  
      @Override  
      public String getMessage() {  
           return "JSF - Spring Integrtion " + name;  
      }  
 }  

6. Now Create Faces-Config.xml with following information in WEB-INF folder:
 <?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">  
      <application>  
           <locale-config>  
                <default-locale>en</default-locale>  
           </locale-config>  
           <resource-bundle>  
                <base-name>messages</base-name>  
                <var>msg</var>  
           </resource-bundle>  
           <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>  
      </application>  
 </faces-config>  

7. Also Create the applicationContext.xml in resources folder:
 <beans xmlns="http://www.springframework.org/schema/beans"  
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
      xsi:schemaLocation="http://www.springframework.org/schema/beans   
                            http://www.springframework.org/schema/beans/spring-beans.xsd  
                         http://www.springframework.org/schema/context   
                         http://www.springframework.org/schema/context/spring-context.xsd">  
      <context:component-scan base-package="com.jsf.app.managedbean,com.jsf.app.service" />  
 </beans>  

8. Now create the jsf page in the webapp/pages/ folder as shown below:
 <?xml version="1.0" encoding="UTF-8"?>  
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"   
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
 <html xmlns="http://www.w3.org/1999/xhtml"  
      xmlns:h="http://java.sun.com/jsf/html">  
 <h:body>  
      <h1>JSF 2.0 + Spring Example</h1>  
            #{userBean.printMsgFromSpring}  
   </h:body>  
 </html>  

9. Finally add the Log4j.xml file for logging purpose inside the resources folder as shown in below:
 <?xml version="1.0" encoding="UTF-8"?>  
 <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >  
 <log4j:configuration>  
      <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">  
           <param name="Target" value="System.out" />  
           <layout class="org.apache.log4j.PatternLayout">  
                <!-- <param name="ConversionPattern" value="[%d{ISO8601}] %-5p [%c] %m %n" />     -->  
                <param name="ConversionPattern" value="%-5p [%c] %m %n" />  
           </layout>  
      </appender>       
      <appender name="STDERR" class="org.apache.log4j.ConsoleAppender">  
           <param name="Target" value="System.err" />  
           <layout class="org.apache.log4j.PatternLayout">  
                <param name="ConversionPattern" value="[%d{ISO8601}] %-5p [%c] %m %n" />  
           </layout>  
           <filter class="org.apache.log4j.varia.LevelRangeFilter">  
                <param name="LevelMin" value="ERROR" />  
                <param name="LevelMax" value="FATAL" />  
           </filter>  
      </appender>  
      <appender name="ROLLING_FILE" class="org.apache.log4j.RollingFileAppender">  
           <!-- param name="File" value="c:/logs/miis30.log" /-->  
           <param name="File" value="jsf.log" />  
           <param name="Append" value="true" />  
           <param name="MaxFileSize" value="5120KB" />  
           <param name="MaxBackupIndex" value="5" />  
           <layout class="org.apache.log4j.PatternLayout">  
                <param name="ConversionPattern" value="[%d{ISO8601}] %-5p %m%n" />  
           </layout>  
      </appender>  
      <root>  
           <level value="ERROR" />  
           <appender-ref ref="STDERR" />  
      </root>    
      <root>  
           <level value="DEBUG" />  
           <appender-ref ref="STDOUT" />  
      </root>   
 </log4j:configuration>  

10. Finally to run the application, right click the project->maven->maven clean,
again right click project->maven->maven install, this will create the war file.
Take a war file and deploy in the tomcat server and run the server as:
 http://localhost:8088/jsf/pages/jsfspring.xhtml