JSF 2, Spring 3 example – The Registration App

Today we are going to show you how to integrate JSF 2 with Spring 3. Our JSF 2 Spring 3 example application is the implementation of the Workshop registration use case. Here is how it looks like.

JSF 2 Spring 3 Example - Workshop registration page

JSF 2 Spring 3 Example – Workshop registration page

JSF 2 Spring 3 Example - Workshop registration Success

JSF 2 Spring 3 Example – Workshop registration Success

Application displays a form where you enter your personal data. After clicking on the Register button, data from the form is being read by the JSF Bean and then passed to the Business Layer which is managed by the Spring 3 framework. When you register in this application you will find this two lines in the Server log indicating that data from the form was passed throught the JSF Bean to the Spring managed service.

RegistrationUserBean:: Registering user John Doe, with email jdoe@test.com
RegistrationBoImpl:: Registering user John Doe, with email jdoe@test.com

This project was developed using the Eclipse IDE. To find out how to configure your development environment please refer to our earlier tutorials:
Maven 3 installation and configuration
Maven 3 Eclipse plugin setup
To see how to create a base project that was used in this tutorial please visit our earlier tutorial and follow the 7 steps listed there – Creating Maven 3 WebApp project.

The project structure is shown below.

JSF 2 Spring 3 Example - Eclipse project structure

JSF 2 Spring 3 Example – Eclipse project structure

pom.xml

Here is project’s pom.xml file. Since we are using JBoss AS 7.x to run this application all the JSF2 artifacts are marked as provided. You don’t need them in the resulting WAR archive. JBoss comes bundled with JSF 2 implementation. Today all the popular JEE Application servers like WebLogic, WebSphere, Glassfish etc. comes bundled with the JSF 2 implementation.
On the other hand all the Spring 3 artifacts will be placed in the WEB-INF/lib directory of the WAR file.

<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>com.itcuties.examples.webapps</groupId>
  <artifactId>jsf2-spring3-registration-webapp</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>Sample Registration WebApp with JSF 2 and Spring 3</name>
  <url>http://www.itcuties.com</url>
  <dependencies>
    <!-- JSF 2 API -->
	<dependency>
		<groupId>com.sun.faces</groupId>
		<artifactId>jsf-api</artifactId>
		<version>2.2.0-m07</version>
		<scope>provided</scope>
	</dependency>
	<!-- JSF 2 Implementation -->
	<dependency>
		<groupId>com.sun.faces</groupId>
		<artifactId>jsf-impl</artifactId>
		<version>2.2.0-m07</version>
		<scope>provided</scope>
	</dependency>
	<!-- Spring core -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-core</artifactId>
		<version>3.2.0.RELEASE</version>
	</dependency>
 	<!-- Spring web -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-web</artifactId>
		<version>3.2.0.RELEASE</version>
	</dependency>
  </dependencies>
  <build>
    <finalName>registration</finalName>
  </build>
</project>

web.xml

You need to configure JSF2 in your web.xml file. JSF2 is implemented as a Servlet which processes URL in your application, in our case we map every URL that ends with *.xhtml to the Faces Servlet.
Spring 3 support in the application is enabled by adding org.springframework.web.context.ContextLoaderListener and org.springframework.web.context.request.RequestContextListener in the listener section.

<!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>
	<display-name>JSF 2 + Spring 3 Integration example</display-name>
	<!-- The welcome page -->
	<welcome-file-list>
		<welcome-file>index.xhtml</welcome-file>
	</welcome-file-list>

	<!-- Spring listeners -->
	<listener>
		<listener-class>
			org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>
	<listener>
		<listener-class>
			org.springframework.web.context.request.RequestContextListener
		</listener-class>
	</listener>

	<!-- Start JSF -->
	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<!-- JSF URL mapping -->
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.xhtml</url-pattern>
	</servlet-mapping>

</web-app>

faces-config.xml

Since we are using Spring annotations in the JSF beans we need to configure org.springframework.web.jsf.el.SpringBeanFacesELResolver.

<?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_1.xsd"
	version="2.1">
 
	<application>
		<el-resolver>
    		    org.springframework.web.jsf.el.SpringBeanFacesELResolver
		</el-resolver>
  	</application>
 
</faces-config>

applicationContext.xml

Spring configuration file contains only one tag, the context:component-scan. If you use this kind of configuration you enable Spring scanning feature. This way Spring will scan your classpath for the Spring annotations in your classes and will automatically create the service implementation instances, inject dependencies etc. All the usual Spring stuff will happen automatically ;)

<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-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
 
    <!-- Scan the com.itcuties.registration package for Spring -->
	<context:component-scan base-package="com.itcuties.registration" />
 
</beans>

index.xhtml

This is the view of the application. It is very simple. This form consists of 3 input text fields and a button. registrationUserBean JSF bean is connected to the form. Bean’s attributes firstname, lastname and email, are connected as the input text fields values and register method is connected as the form action.

<?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>Workshop registration form</title>
    </h:head>
    <h:body>
    	<h3>Workshop registration</h3>
    	<h:form>
    	   <h:inputText value="#{registrationUserBean.firstname}" />
    	   <h:inputText value="#{registrationUserBean.lastname}" />
    	   <h:inputText value="#{registrationUserBean.email}" />
    	   <h:commandButton id="button" value="Register" action="#{registrationUserBean.register}" />
    	   
    	   <h:messages />
    	   
    	</h:form>
    </h:body>
</html>

RegistrationUserBean

Here is the JSF bean class. It is annotated with the @ManagedBean and @SessionScoped annotations which tell the JSF framework that this class is a session bean. There is also the @Component used which tell Spring engine that this class is a Spring component as well.
This class is simple it consists of the firstname, lastname, email attributes, the registrationBo reference and the register() method.
This first three attributes are being set by the JSF engine when the form is being submitted.
register() method is the one called when the form is being submitted.
registrationBo reference is annotated with the @Autowired annotation which tells the Spring framework that a service object needs to be injected. This reference is used to call the registerUser() method of the RegistrationBo interface implementation managed by Spring.

package com.itcuties.registration.beans;

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

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

import com.itcuties.registration.bo.RegistrationBo;

/**
 * Registration user JSF bean.
 * 
 * @author itcuties
 *
 */
@Component
@ManagedBean
@SessionScoped
public class RegistrationUserBean {
	
	// This is going to be injected by Spring framework
	@Autowired
	RegistrationBo registrationBo;
	
	private String firstname;
	private String lastname;
	private String email;
	
	/**
	 * Method registers user
	 */
	public void register() {
		// Output some info
		System.out.println("RegistrationUserBean:: Registering user " + firstname + " " + lastname + ", with email " + email);
		
		// Call the business object to register the user
		registrationBo.registerUser(firstname, lastname, email);
		
		// Set the message here
		FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Registration success", "success");  
        FacesContext.getCurrentInstance().addMessage(null, msg);
	}
	
	// Set the registrationBo attribute used by Spring
	public void setRegistrationBo(RegistrationBo registrationBo) {
		this.registrationBo = registrationBo;
	}

	public String getFirstname() {
		return firstname;
	}
	
	public void setFirstname(String firstname) {
		this.firstname = firstname;
	}
	
	public String getLastname() {
		return lastname;
	}
	
	public void setLastname(String lastname) {
		this.lastname = lastname;
	}
	
	public String getEmail() {
		return email;
	}
	
	public void setEmail(String email) {
		this.email = email;
	}
	
}

RegistrationBo

This is the sample registration interface of our application.

package com.itcuties.registration.bo;

/**
 * Registration Business Object interface.
 * @author itcuties
 *
 */
public interface RegistrationBo {
	/**
	 * Register user method
	 * @param firstname
	 * @param lastname
	 * @param email
	 */
	public void registerUser(String firstname, String lastname, String email); 
}

RegistrationBoImpl

This is the implementation of the RegistrationBo interface. Notice that this class is annotated with the @Service annotation. This tells Spring framework that this class is a Spring service. The instance of the class is being created and injected where needed when Spring engine scans your classpath automatically.

package com.itcuties.registration.bo.impl;

import org.springframework.stereotype.Service;

import com.itcuties.registration.bo.RegistrationBo;

/**
 * Registration Business Object implementation. 
 * @author itcuties
 *
 */
@Service
public class RegistrationBoImpl implements RegistrationBo {

	public void registerUser(String firstname, String lastname, String email) {
		// Output some info
		System.out.println("RegistrationBoImpl:: Registering user " + firstname + " " + lastname + ", with email " + email);
		
		// TODO: Contact your database here
		// ...
	}
	
}

Running the application

To build this code you need to call the mvn package command. As a result the registration.war package gets created in the target directory of your project. Deploy the WAR package on the application server. As mentioned before the application server you are deploying your application at has to have a JSF implementation in it’s classpath. Using JBoss, WebLogic, WebSphere, Glassfish or any other application platform that comes bundled with the JSF 2 implementation is recommended.

Download this sample code here.

This code is available on our GitHub repository as well.

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Java by Example App is available at Google Play Store NOW