JSF 2.2 Spring4 integration example using spring annotations

In this tutorial, let us see how to integrate JSF 2.2 with Spring 4 in Eclipse with maven support. Multilayer Applications can be developed by using more than one frameworks such as JSF (Web Layer), Spring (Service and Business Layer) and Hibernate (Persistence Layer). In this example, we are using Spring and JSF. JSF Framework may be suitable for building rich web user interfaces with component-based UI support. Spring framework can be used as middle tier for building serverside business logic. Now the question is how to integrate JSF web layer with Spring service layer. The easiest way is to use SpringBeanFacesELResolver class which allows to inject dependencies into JSF-Managed beans.

To use the class, define SpringBeanFacesELResolver in faces-config.xml as given below.

<faces-config>
  <application>
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
    ...
  </application>
</faces-config>

Now let us see how to inject Spring bean (business object) into JSF managed bean. This can be done using Spring annotations like @Component, @Service and @Autowired. You can also use XML Schema OR  JSR- 330 Annotations to inject Spring bean.

In this example, let us see JSF and Spring integration using Spring Annotations.

Technologies used in this project :

1. JSF 2.2

2. Spring 4.17

3. Maven 3.0

4. Eclipse Java EE IDE

5. Tomcat 7.0

Directory Structure :

JSF Spring Integration

Project Dependencies:

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>net.javaonline.jsfspring</groupId>
  <artifactId>JSF_DEMO</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>JSF_SPRING Maven Webapp</name>
  <url>http://maven.apache.org</url>
   <dependencies>
    <dependency>
	<groupId>com.sun.faces</groupId>
	<artifactId>jsf-api</artifactId>
	<version>2.2.11</version>
    </dependency>

    <dependency>
	<groupId>com.sun.faces</groupId>
	<artifactId>jsf-impl</artifactId>
	<version>2.2.11</version>
	</dependency>

    <dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-core</artifactId>
	<version>4.1.7.RELEASE</version>
</dependency>

    <dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>4.1.7.RELEASE</version>
</dependency>

	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-web</artifactId>
		<version>4.1.7.RELEASE</version>
	</dependency>

    <dependency>
	<groupId>javax.el</groupId>
	<artifactId>javax.el-api</artifactId>
	<version>3.0.1-b04</version>
	</dependency>

     <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

   	<build>
	 <outputDirectory>src/main/webapp/WEB-INF/classes</outputDirectory>
        <finalName>RESTFUL</finalName>
		<resources>
			<resource>
				<directory>src/main/resources</directory>
			</resource>
			<resource>
				<filtering>false</filtering>
				<directory>src/main/java</directory>
				<includes>
					<include>*</include>
				</includes>
				<excludes>
					<exclude>**/*.java</exclude>
				</excludes>
			</resource>
		</resources>

	</build>

</project>

Now we will create a JSF web page, JSF managed bean and Spring business object. Then we will inject the Spring bean into JSF managed bean so that the business logic can be accessed in the JSF managed bean. The web page accepts Product details such as itemcode, itemname, maximumretailprice(mrp), stock.

Step 1: Create a Maven Project (JSF_DEMO) in Eclipse (File->New->Maven Project)
Step 2: Creating a JSF WebPage (itemmasteradd.xhtml)
<?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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">

<h:head>
<title>JSF Spring  Integration Example</title>
</h:head>
<h:body>
		<h3>Item Master</h3>
	<h:form>
		 <h:outputLabel> Item Code</h:outputLabel>
		<h:inputText value="#{itemMasterBean.icode}"></h:inputText>
		 <h:outputLabel> Item Name</h:outputLabel>
		<h:inputText value="#{itemMasterBean.item_name}"></h:inputText>
 	    <h:outputLabel>MRP</h:outputLabel>
		<h:inputText value="#{itemMasterBean.mrp}"></h:inputText>
 	    <h:outputLabel>Stock</h:outputLabel>
		<h:inputText value="#{itemMasterBean.stock}"></h:inputText>

		<h:commandButton value="Add" action="#{itemMasterBean.addItem}"></h:commandButton>
	</h:form>
</h:body>
</html> 

The above page accepts item code, item name, price and initial stock.

Step 3: Creating JSF Managed bean

ItemMasterBean.java

package net.javaonline.web.jsf.inventory.itemmaster.ui.bean;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;

import net.javaonline.spring.inventory.itemmaster.bo.ItemMasterBo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@ManagedBean(name="itemMasterBean")
@RequestScoped
public class ItemMasterBean {
private String icode;
private String item_name;
private float mrp;
private int stock;

// to inject ItemMasterBOImpl object by Spring
@Autowired
ItemMasterBo itemMasterBo;

public void addItem()  {

	// Accessing the business object for adding item
	boolean success=itemMasterBo.addItem(icode,item_name, mrp, stock);

	FacesMessage msg;

	if (success)
			 msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "item added to the master successfully", "success");
	else
			msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "error in adding item", "failure");

	FacesContext.getCurrentInstance().addMessage(null, msg);
}

public ItemMasterBo getItemMasterBo() {
	return itemMasterBo;
}

public void setItemMasterBo(ItemMasterBo itemMasterBo) {
	this.itemMasterBo = itemMasterBo;
}

public String getIcode() {
	return icode;
}
public void setIcode(String icode) {
	this.icode = icode;
}

public String getItem_name() {
	return item_name;
}

public void setItem_name(String item_name) {
	this.item_name = item_name;
}

public float getMrp() {
	return mrp;
}

public void setMrp(float mrp) {
	this.mrp = mrp;
}

public int getStock() {
	return stock;
}

public void setStock(int stock) {
	this.stock = stock;
}

}
Step 4: Creating business object in Spring

ItemManagerBO.java


package net.javaonline.spring.inventory.itemmaster.bo;

public interface ItemMasterBo {

	public boolean addItem(String item_code,String item_name, float mrp, int stock);
}

ItemManagerBOImpl.java

package net.javaonline.spring.inventory.itemmaster.bo;

import net.javaonline.spring.inventory.itemmaster.bo.dao.ItemMasterDAOImpl;

import org.springframework.stereotype.Service;

/**
 * ItemMaster BO implementation
 *
 */
@Service
public class ItemMasterBoImpl implements ItemMasterBo {

	public boolean addItem(String item_code,String item_name, float mrp, int stock) {

		boolean result=false;

    //	Write Business Logic here... 

		//....
		//....

		System.out.println("Item Details");

		System.out.println("item_code : "+ item_code + " item_name:" + item_name + " Maximum Retail Price : "+ mrp + " Stock : "+stock);

		if (mrp<=0 || stock<=0)
			result= false;
		else
		{
//This class may be injected using spring DI
			ItemMasterDAOImpl itemMasterDAO=new ItemMasterDAOImpl();
			//Calling Data Access Object
			return itemMasterDAO.add(item_code, item_name, mrp, stock);
		}		

		return result;

	}

} 
Step 5: Write Necessary DAO code for Database access and adding product details

ItemMasterDAO.java


package net.javaonline.spring.inventory.itemmaster.bo.dao;

public interface ItemMasterDAO {

	public boolean add(String item_code,String item_name, float mrp, int stock);

} 
package net.javaonline.spring.inventory.itemmaster.bo.dao;

public class ItemMasterDAOImpl implements ItemMasterDAO {

	public boolean add(String item_code,String item_name, float mrp, int stock)
	{

		//Write database code here for accessing  DB and add the item in table.

		//On successful adding the item 

		return true;

		//else return false;

	}

} 

Spring annotations used for injection / auto-detection of Spring bean:

@Autowired: Makes any field, setter method or constructor to be auto-wired. In our example, ItemMasterBoImpl bean is automatically created and injected

@Component: A streotype annotation which enables any class (in our example, ItemMasterBean.java) for auto-detection when using annotation-based configuration.

@Service: The class annotated with "Service" is automatically detected by spring and registered as beans with the ApplicationContext. This requires the below configuration in applicationContext.xml

<context:component-scan base-package="net.javaonline.spring.inventory,net.javaonline.web.jsf.inventory" />

Step 6: Define necessary configuration in the following XML Files as given below

1. faces-config.xml

2. applicationContext.xml

3. web.xml

1. faces-config.xml


<?xml version="1.0" encoding="UTF-8"?>
<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">
<application>
	  <resource-bundle>
		<base-name>JSF Spring Integration</base-name>
		<var>labels</var>
	   </resource-bundle>
     </application>

	<application>
		<el-resolver>
    		    org.springframework.web.jsf.el.SpringBeanFacesELResolver
		</el-resolver>
  	</application>

</faces-config>

2. applicationContext.xml

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

     <!-- For Scanning the packages net.javaonline.spring.inventory & net.javaonline.web.jsf.inventory and registering the  beans with the applicationContext-->
	<context:component-scan base-package="net.javaonline.spring.inventory,net.javaonline.web.jsf.inventory" />

</beans>

3. web.xml

<?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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>JSF Spring Integration</display-name>
  <welcome-file-list>
    <welcome-file>faces/index.xhtml</welcome-file>
  </welcome-file-list>
<listener>
		<listener-class>
			org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>
	<listener>
		<listener-class>
			org.springframework.web.context.request.RequestContextListener
		</listener-class>
	</listener>

  <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>

  <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>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
  </context-param>

</web-app>

Run the application:

http://localhost:8080/JSF_DEMO/itemmasteradd.xhtml

jsf spring integration1

 

Output:

Console Output:

jsf spring integration2

Result:

jsf spring integration3

 

References :

1. SpringBeanFacesELResolver

2. Stereotype Annotations

You may also like

Leave a Reply

4 Comments on "JSF 2.2 Spring4 integration example using spring annotations"


Guest
Tavo Alva
9 months 8 days ago

Hi.
First, thank you very much for this tutorial and for share your time.
Second, i have a problem when i started tomcat:

Caused by: java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: The resource path [WEB-INF/faces-config.xml] is not valid
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at com.sun.faces.config.ConfigManager.getConfigDocuments(ConfigManager.java:751)

Can you help me?.

Best Regards.

Tavo

Guest
Camilo Cervantes
10 months 29 days ago

Can you please share the project folder ?