The integration issue between JSF and Spring
JSF 2.2 comes with several cool features: html5 support, resource contracts, flow scope, etc. As a JSF enthusiast, you may want to use it in your new project or update your old project. But most likely you project already has spring MVC as it is the 'glod' standard.It is always a trouble to using Spring together with JSF. JSF is a completely MVC framework while Spring WebMVC is designed for other view technology to plugin. When it comes to JSF, you will find many function duplication between MVC and JSF. This duplication will definitely cause trouble for JSF developer. For example, are you going to use Spring view mapping or JSF navigation? To handle a JSF commandButton action, are you going to use Spring WebFlow action or JSF action Listener? In a Spring WebFLow, can you still use the whole JSF process flow?
This is just the beginning of the problem. JSF 2.2 is tightly coupled with CDI for some of its new feature. For example, it uses CDI for flowScope and new ViewScope.However, Spring does not fully support CDI in JEE. I guess it will become more and more difficult in using JSF under Spring as new JSF comes out in future.
Here I did some experiment to figure out how to use JSF 2.2 besides Spring Framework. The principle is not using Spring MVC for JSF.
Using two CDI frameworks
JSF 2.2 definitely needs CDI framework if FlowScope or ViewScope is used. Please note that ViewScope has many troubles in JSF 2.1 and it is the most used scope in JSF in my opnion. So I assume that CDI is definitely needed. Spring itself is a CDI framework, but not compliant with JEE standard(JSR 330). Besides Spring, we need a JSR 330-compliant CDI libary.Do not use Spring MVC
Do not use any Spring MVC feature for your Facelet. This means you JSF facelet page is driven by FacesServlet, not by Spring MVC DispatchServlet.Look up Spring Bean
So how can you find Spring bean in JSF code? Here is a piece code to show thisApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());
SBeanApp beanApp=ctx.getBean("sBeanApp", SBeanApp.class);
System.out.println("found bean with desc "+beanApp.getDesc());
I post my pom.xml and web.xml to show a real project looks like:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.jason</groupId>
<artifactId>stdjsf</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>stdjsf</name>
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- Servlet Spec 3.0 -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>7.0.42</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jsp-api</artifactId>
<version>7.0.42</version>
<scope>provided</scope>
</dependency>
<!-- JSF 2.2 -->
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>
<!--
Enables common annotations,
which is provided by default in an EE container, on Tomcat Begin-->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>3.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.13</version>
</dependency>
<!-- Not used for JSF, may be used for other purpose such as RESTful communication -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.2.5.RELEASE</version>
</dependency>
<!-- WELD -->
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet</artifactId>
<version>2.0.4.Final</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
<debug>true</debug>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
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"
version="3.0">
<display-name>stdjsf</display-name>
<!-- Spring -->
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
<!-- The master configuration file for this Spring web application -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/config/web-application-config.xml
</param-value>
</context-param>
<!-- Enforce UTF-8 Character Encoding -->
<filter>
<filter-name>charEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>charEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Loads the Spring web application context -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<!-- JSF -->
<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>*.xhtml</url-pattern>
<url-pattern>/javax.faces.resource/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.application</param-value>
</context-param>
<!-- <context-param>
<param-name>javax.faces.CONFIG_FILES</param-name>
<param-value>/project/project-flow.xml</param-value>
</context-param> -->
<context-param>
<param-name>javax.faces.CLIENT_WINDOW_MODE</param-name>
<param-value>url</param-value>
</context-param>
<!-- will be invoked automatically by Mojarra -->
<!-- <listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener> -->
<!-- WELD -->
<listener>
<listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>
<resource-env-ref>
<description>Object factory for the CDI Bean Manager</description>
<resource-env-ref-name>BeanManager</resource-env-ref-name>
<resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
</resource-env-ref>
</web-app>
Problem solved. You can use your favorite JSF library and keep Spring enthusiast happy at the same time.
Excelent post, I'll test it.
ReplyDeleteBig data is a term that describes the large volume of data – both structured and unstructured – that inundates a business on a day-to-day basis. big data projects for students But it’s not the amount of data that’s important.Project Center in Chennai
DeleteSpring Framework has already made serious inroads as an integrated technology stack for building user-facing applications. Corporate TRaining Spring Framework the authors explore the idea of using Java in Big Data platforms.
Spring Training in Chennai
The new Angular TRaining will lay the foundation you need to specialise in Single Page Application developer. Angular Training
Great, but, does it run on Tomcat 7.x?
ReplyDeletegreat
ReplyDeleteInteresting Article
ReplyDeleteSpring online training Spring online training Spring Hibernate online training
Spring Hibernate online training
spring training in chennai
spring hibernate training in chennai
That is very interesting; you are a very skilled blogger. I have shared your website in my social networks! A very nice guide. I will definitely follow these tips. Thank you for sharing such detailed article.
ReplyDeletePhp course in chennai
ReplyDeleteNice infromation
Selenium Training In Chennai
Selenium course in chennai
Selenium Training
Selenium Training institute In Chennai
Best Selenium Training in chennai
Selenium Training In Chennai
ReplyDeleteRpa Training in Chennai
Rpa Course in Chennai
Rpa training institute in Chennai
Best Rpa Course in Chennai
uipath Training in Chennai
Blue prism training in Chennai
ReplyDeleteData Science Training In Chennai
Data Science Course In Chennai
Data Science Training institute In Chennai
Best Data Science Training In Chennai
ReplyDeletePython Training In Chennai
Python course In Chennai
Protractor Training in Chennai
jmeter training in chennai
Loadrunner training in chennai
Really a supportive work for writing a good article.Any one can enjoy it with the style of writing. really happy to read.
ReplyDeleteAi & Artificial Intelligence Course in Chennai
PHP Training in Chennai
Ethical Hacking Course in Chennai Blue Prism Training in Chennai
UiPath Training in Chennai