Eugene Burtsev's blog

JSF2 + Spring Framework Example

Just recently I’ve discovered the Spring Framework. IMHO it is amazing framework. And I decided to rewrite a couple of my applications using Spring. Below I tell how to integrate Spring and JSF2

Dependencies

The first step is to add the org.springframework:spring-web artifact as project dependency:

pom.xml
1
2
3
4
5
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>3.1.1.RELEASE</version>
</dependency>

Setup

To make it work you must configure listeners in web.xml, as shown in the following example:

web.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      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="jsf2-spring-example" version="2.5">

  <display-name>jsf2-spring-example Application</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>

  <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-context.xml</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>*.jsf</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>/faces/*</url-pattern>
  </servlet-mapping>

</web-app>

It is also necessary to set custom el-resolver from Spring instead of the standard to allow Spring manage beans. Change faces-config.xml as in following piece of code:

faces-config.xml
1
2
3
4
5
6
7
8
9
<?xml version="1.0"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xi="http://www.w3.org/2001/XInclude"
    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">

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

</faces-config>

Now configure spring-context.xml. You just need to set base-package property for context:component-scan:

spring-context.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<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/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

  <!-- enable component scanning -->
  <context:component-scan base-package="net.burtsev.example" />

  <!-- enable autowire -->
  <context:annotation-config />

</beans>

Code

Now, after we make all necessary settings, we can write some code:

index.xhtml

index.xhtml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:ui="http://java.sun.com/jsf/facelets" template="/templates/main.xhtml">

  <ui:define name="title">Home</ui:define>

  <ui:define name="body">
      <h:form prependId="false">
          <h:inputText value="#{testBean.name}" />
          <h:commandButton action="#{testBean.sayHelloAction}" value="Say Hello"/>
          <br/>
          #{testBean.hello}
      </h:form>
  </ui:define>

</ui:composition>

TestBean.java

here we using @Controller annotation instead of JSF @ManagedBean and @Scope to set bean scope. List of all possible scopes you can see here: Spring Framework Reference. Also in spring I not found view scope. But I found solution here and here

TestBean.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package net.burtsev.example.web;

import java.io.Serializable;

import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

@Controller
@Scope("session")
public class TestBean implements Serializable {

  private static final long serialVersionUID = -1;

  private String name;
  private String hello;

  public void sayHelloAction() {
      hello = StringUtils.isNotBlank(name) ? "Hello " + name : "";
  }

  public String getName() {
      return name;
  }

  public void setName(String name) {
      this.name = name;
  }

  public String getHello() {
      return hello;
  }

  public void setHello(String hello) {
      this.hello = hello;
  }
}

Run example

Run it and follow this link: http://localhost:8080/jsf2-spring-example/index.jsf It’s works! :)

P.S. Full project you can be downloaded from my github repository

Comments