Integrating JSF and Spring
December 25, 2005 21 Comments
We’re currently using JSF and Spring together and I could say that integration of these two frameworks is not so hard thanks to the Springs facilities. I am using two different ways when I need to access the beans managed by spring. One is to use the delegating resolver and the other is to the FacesContextUtils
Update: See this post about a better alternative, using Spring to manage JSF Beans.
1) Delegating Resolver
For example you have a facade called FacadeService and it has a dependency to another service called “SomeService” which implements “ISomeService”. Also “SomeService” is managed by spring. The first is to define the FacadeService as;
package yourpackagename;
public class FacadeService {
private ISomeService someService;
public ISomeService getSomeService() {
return someService;
}
public void setSomeService(ISomeService someService) {
this.someService = someService;
}
}
The next step is to define this FacadeService as a managed bean in the faces-config.xml by; The other bean definition is a backing bean of your jsf page.
<managed-bean>
<managed-bean-name>facadeService</managed-bean-name>
<managed-bean-class>
yourpackagename.FacadeService
</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
<managed-property>
<property-name>someService</property-name>
<property-class>
packagename.ISomeService
</property-class>
<value>#{someService}</value>
</managed-property>
</managed-bean>
<managed-bean>
<managed-bean-name>backingBeanName</managed-bean-name>
<managed-bean-class>
yourpackagename.backingBeanClass
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>facadeService</property-name>
<property-class>
packagename.FacadeService
</property-class>
<value>#{facadeService}</value>
</managed-property>
</managed-bean>
* Also the delegating resolver must be defined in faces-config.xml between the application tag as following;
<application>
<variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>;
</application>
* Next step is putting the listener of spring goes into the web.xml and telling the location of spring’s xml
<context-param>
<param-name>contextConfigLocation </param-name>
<param-value>/WEB-INF/applicationContext.xml </param-value>
</context-param>
The place of applicationContext.xml is optional, you should also put it under classes and refer it like classpath:/applicationContext.xml.
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
* Here is the spring’s xml to manage the someService bean
<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE beans PUBLIC
“-//SPRING//DTD BEAN//EN”
“http://www.springframework.org/dtd/spring-beans.dtd”>
<beans default-autowire=”no” default-lazy-init=”false”
default-dependency-check=”none”>
<bean id=”someService” class=”yourpackagename.SomeService”></bean>
</beans>
* So thats all metadata you need to configure, the final step is to add the FacadeService to the code behind of your jsf page by simply adding this; For example you have a backing bean called YourBackingBean.java, Faces inject facadeService to this bean since we have configured it. Also the spring bean (some service) is injected via the delegation variable resolver when creating the facadeService.
public class YourBackingBean{
protected FacadeService facadeService;
public FacadeService getFacadeService() {
return facadeService;
}
public void setFacadeService(FacadeService facadeService) {
this.facadeService = facadeService;
}
}
There is an important note here, using the #{facadeService} you can get the value of the FacadeService managed by Faces, the default variable resolver of JSF will bring it for you. Also you can get the SomeService object by writing the appropriate accessor methods and replacing the value binding expression with #{someService}. The default variable resolver will not find “someService” and the responsibility will pass to the DelegatingVariableResolver of Spring which will return the someService name. Long story short, here comes the fun part, accessing the spring bean from code behind, for example at anywhere in your jsf code behind you can reach the spring bean by;
getFacadeService().getSomeService().someMethod(); //If everything is ok, hopefully no npe
These steps allows the JSF-Spring integration, inversion of control is applied both by spring and faces, facadeservice is managed by Faces and these are wired using the delegating variable resolver of spring. Important thing is spring bean is not injected by spring, the wiring is done by faces. Spring’s role is a container in this case.
2) Using the FacesContextUtils
I always see this one as the alternative and I dont use it unless I have to. For example, I have created a custom jsf component and a custom variable resolver. Both of these needed to use spring beans. So thats why I’ve reached spring directly. FacesContextUtils is an utility class that is located in spring framework.
ISomeService someService = (ISomeService) FacesContextUtils
.getWebApplicationContext(FacesContext.getCurrentInstance())
.getBean(“someService”);
someService.someMethod();
To sum up, I could say using these two frameworks is fun and spring’s mechanisms make it very easy.You can either use the delegating resolver or FacesContextUtils to use the beans managed by Spring and Faces together.
Hello,
interesting text. Why du you prefer the first solution (Delegating Resolver)? It seems that the second solution is much easier.
best regards
Well, the first one is more useful in many cases and does the jobs for you. You can hand over the injection business to faces, do not need coding to reach spring beans which leads to better design:)
it so nice to read the tutorial but when it comes to deploy it then u see many errors. not because of the code but the code is not complete.
I do suggest to have the code in a zip file for running. I do thank anyone to zip me the code to adapt it to myeclipse and I am ready to help in return.
alhakim55at yahoo
Hi,
I wish you went into details regarding scope with spring 2.0. Im having real trouble getting the delegating variable resolver to pick up session or request scoped beans from spring.
Basically I am trying to get rid of JSF IoC container altogether. The RequestContextListener should let spring be aware of http scopes, but there seems to be some behind the scenes enigma here.
I think this tutorial would be much more complete with information on spring web context.
Any idea on how to best integrate the Spring Interception with JSF Message bundles?
E.g. suppose you use Spring for Security. Via an advisor. (pointcut = set of distinct methods to secure & interceptor = checking the required privs) Suppose smth goes wrog; the user doesn’t have the necessary privs –> how, from the Spring Interceptor, add a message to the page, so that the user knows the prolbem is he doens’t have enough privileges?
Wolf
Hi All
I am using JSF 1.1_01, Spring 1.2.6, Tomcat 5.0.28.
I am getting following error
javax.servlet.jsp.JspException: javax.faces.FacesException: javax.faces.el.EvaluationException: Expression Error: Named Object: ‘springBean’ not found.
The root cause for the error is “” under from JSF which references Spring Bean. It is not able to evaluate JSF Expression Language. Then i tried following permutations and combinations
-> instead of using JSF EL, i hardcoded the property value and it worked
Any pointers/suggestions will be highly appreciate. I am working on this for more than a week
Regards
Bansi
This code:
facadeService
application
yourpackagename.FacadeService
ISomeService is interface
someService is instance of class implement ISomeService, and
config in the spring’s xml, but when i call someService.method() in FacadeService, it alway throws nullPointerException, why so ???
Are you sure add the delegating variable resolver and there’s a spring bean with id someService?
I had added delegating variable resolver and there’s a spring bean with id someService
When i config someService bean in faces-config.xml i can get someService success but when i config someService bean in the spring’s xml, i can get it from faces-config.xml but when I use FacesContextUtils, i can get someService in spring’s xml.
What are the Jars adn version used?And also what is the JDK version been used?
Read this http://www.springframework.org/docs/reference/mvc.html#mvc-introduction-pluggability. Look under “13.1.1. Pluggability of other MVC implementations”. None of your managed beans should ever have to be accessed by spring. If you are using jsf for your MVC implementation, why in the world would you want your managed beans to be in Spring?
If you have a DAO object managed by spring for example, then in your managed bean you can access it that using the spring ApplicationContext that is already provided. You can access by getting the context from the FacesContext object. First, as explained, you’ll have initialize the ApplicationContext for spring in the servlet context when jsf starts. It’s simple really. That’s all you need to integrate the two. Here is an example of accessing it, assuming you loaded and initialized spring’s ApplicationContext in the ServletContext when jsf web application started.
//This returns a ServletContext when running
//in the servlet container
ServletContext ctx = (ServletContext)FacesContext.getExternalContext().getContext();
//Get the ApplicationContext for spring
ApplicationContext springContext = (ApplicationContext)ctx.getAttribute(“springContext”);
MyDaoBean bean = (MyDaoBean)springContext.getBean(“daoBean”);
–Where beanName is a bean defined in the spring application.xml
This is the way to do it. To review the application context, go to http://www.springframework.org/docs/reference/beans.html#beans-factory-class and look in section 3.2.2
JSF beans are not injected to the spring beans, spring beans are injected to the jsf beans. Please read the entry first before commenting:)
How to configure jsf with spring
is it possible jsf sping with hibernate
Very interesting and usefull
I´m having problems to configure SpringJSFDWR but now it´s a piece of cake
Thanks
I have written the program and it is giving error
,it’s coming for jsp output in jsf but when used jsf tags
Can you send me the full code
Having Spring inject my business layer Spring beans into my JSF backing beans is just fantastic. The DelegatingVariableResolver was what I’d been missing.
And, it worked first time! I’m luckier than usual today it seems…
Absolutely brilliant, thanks!
Has anyone been able to use Spring AOP on a JSF method using this? The following blog explains how to, but I am not able to get it working…
http://www.jroller.com/page/idotzang?entry=spring_aop_for_a_cleaner
When I integrate JSF 1.2, Facelets and Spring, then run it on tomcat 5.5, it can not work, why so???
This is log:
————————————————-
un 6, 2007 10:49:22 AM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
INFO: The Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jdk1.5.0_06\bin;.;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem
Jun 6, 2007 10:49:22 AM org.apache.coyote.http11.Http11BaseProtocol init
INFO: Initializing Coyote HTTP/1.1 on http-8080
Jun 6, 2007 10:49:22 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 1219 ms
Jun 6, 2007 10:49:22 AM org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
Jun 6, 2007 10:49:22 AM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/5.5.17
Jun 6, 2007 10:49:22 AM org.apache.catalina.core.StandardHost start
INFO: XML validation disabled
log4j:WARN No appenders could be found for logger (org.apache.catalina.startup.TldConfig).
log4j:WARN Please initialize the log4j system properly.
Jun 6, 2007 10:49:23 AM com.sun.faces.config.WebConfiguration
INFO: JSF1018: [alohot] Configuration option ‘javax.faces.STATE_SAVING_METHOD’ set to ‘client’
Jun 6, 2007 10:49:23 AM com.sun.faces.config.WebConfiguration
INFO: JSF1018: [alohot] Configuration option ‘javax.faces.DEFAULT_SUFFIX’ set to ‘.xhtml’
Jun 6, 2007 10:49:23 AM com.sun.faces.config.WebConfiguration
INFO: JSF1018: [alohot] Configuration option ‘com.sun.faces.numberOfViewsInSession’ set to ’15′
Jun 6, 2007 10:49:23 AM com.sun.faces.config.WebConfiguration
INFO: JSF1018: [alohot] Configuration option ‘com.sun.faces.numberOfLogicalViews’ set to ’15′
Jun 6, 2007 10:49:23 AM com.sun.faces.config.WebConfiguration
INFO: JSF1018: [alohot] Configuration option ‘com.sun.faces.injectionProvider’ set to ‘com.sun.faces.vendor.GlassFishInjectionProvider’
Jun 6, 2007 10:49:23 AM com.sun.faces.config.WebConfiguration
INFO: JSF1018: [alohot] Configuration option ‘com.sun.faces.responseBufferSize’ set to ’4096′
Jun 6, 2007 10:49:23 AM com.sun.faces.config.WebConfiguration
INFO: JSF1018: [alohot] Configuration option ‘com.sun.faces.clientStateWriteBufferSize’ set to ’8192′
Jun 6, 2007 10:49:23 AM com.sun.faces.config.WebConfiguration
INFO: JSF1021: [alohot] Configuration option ‘com.sun.faces.validateXml’ – ENABLED
Jun 6, 2007 10:49:23 AM com.sun.faces.config.WebConfiguration
INFO: JSF1021: [alohot] Configuration option ‘com.sun.faces.verifyObjects’ – ENABLED
Jun 6, 2007 10:49:23 AM com.sun.faces.config.WebConfiguration
INFO: JSF1021: [alohot] Configuration option ‘com.sun.faces.forceLoadConfiguration’ – DISABLED
Jun 6, 2007 10:49:23 AM com.sun.faces.config.WebConfiguration
INFO: JSF1021: [alohot] Configuration option ‘com.sun.faces.disableVersionTracking’ – DISABLED
Jun 6, 2007 10:49:23 AM com.sun.faces.config.WebConfiguration
INFO: JSF1021: [alohot] Configuration option ‘com.sun.faces.enableHtmlTagLibValidator’ – DISABLED
Jun 6, 2007 10:49:23 AM com.sun.faces.config.WebConfiguration
INFO: JSF1021: [alohot] Configuration option ‘com.sun.faces.preferXHTML’ – DISABLED
Jun 6, 2007 10:49:23 AM com.sun.faces.config.WebConfiguration
INFO: JSF1021: [alohot] Configuration option ‘com.sun.faces.compressViewState’ – DISABLED
Jun 6, 2007 10:49:23 AM com.sun.faces.config.ConfigureListener contextInitialized
INFO: Initializing Sun’s JavaServer Faces implementation (1.2_01-NIGHTLY_20060603) for context ‘alohot’
Jun 6, 2007 10:49:24 AM com.sun.faces.config.ConfigureListener contextInitialized
INFO: Completed initializing Sun’s JavaServer Faces implementation (1.2_01-NIGHTLY_20060603) for context ‘alohot’
Jun 6, 2007 10:49:24 AM org.apache.catalina.core.StandardContext start
SEVERE: Error listenerStart
Jun 6, 2007 10:49:24 AM org.apache.catalina.core.StandardContext start
SEVERE: Context [/alohot] startup failed due to previous errors
Jun 6, 2007 10:49:25 AM org.apache.coyote.http11.Http11BaseProtocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Jun 6, 2007 10:49:25 AM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
Jun 6, 2007 10:49:25 AM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/16 config=null
Jun 6, 2007 10:49:25 AM org.apache.catalina.storeconfig.StoreLoader load
INFO: Find registry server-registry.xml at classpath resource
Jun 6, 2007 10:49:25 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 3188 ms
————————————————-
Hi,
Can anyone please send me the code of the discussion. Need it urgently…Thanks a lot in advance.
Pingback: Using Spring to Manage JSF Beans « Cagatay Civici’s Weblog
I followed your article – better alternative, using Spring to manage JSF Beans. This worked for my first jsf screen where I display a user list. In the list page I have a datatable with a command link tag having an action listener. I am not able to get to the actionlistener method in the backing bean.
I have seen postings where command link inside a data table is known to cause problems. Does allowing Spring to manage the beans has any further effect?
I am using Spring 2.05, JSF1.2 and Hibernate 3.2. Any pointers woudl be great.
Thanks.