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