Integrating JSF and Spring

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”&gt;

<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.

About these ads

21 Responses to Integrating JSF and Spring

  1. AK says:

    Hello,

    interesting text. Why du you prefer the first solution (Delegating Resolver)? It seems that the second solution is much easier.

    best regards

  2. Ça?atay says:

    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:)

  3. amir says:

    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

  4. rethrick says:

    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.

  5. Wolf Benz says:

    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

  6. Bansi says:

    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

  7. BlackWolf88 says:

    This code:
    facadeService

    yourpackagename.FacadeService

    application

    someService packagename.ISomeService #{someService}

    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 ???

  8. Cagatay says:

    Are you sure add the delegating variable resolver and there’s a spring bean with id someService?

  9. BlackWolf88 says:

    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.

  10. Venkat Gurukrishna says:

    What are the Jars adn version used?And also what is the JDK version been used?

  11. queperknuckle says:

    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

  12. Cagatay says:

    JSF beans are not injected to the spring beans, spring beans are injected to the jsf beans. Please read the entry first before commenting:)

  13. Thangadurai says:

    How to configure jsf with spring

    is it possible jsf sping with hibernate

  14. aleodoni says:

    Very interesting and usefull
    I´m having problems to configure SpringJSFDWR but now it´s a piece of cake

    Thanks

  15. kalyan says:

    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

  16. JC says:

    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!

  17. scott says:

    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

  18. Anonymous says:

    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
    ————————————————-

  19. Praveen says:

    Hi,

    Can anyone please send me the code of the discussion. Need it urgently…Thanks a lot in advance.

  20. Pingback: Using Spring to Manage JSF Beans « Cagatay Civici’s Weblog

  21. VK says:

    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.

Follow

Get every new post delivered to your Inbox.

Join 106 other followers

%d bloggers like this: