ArticlesTutorialsInterview Questions & AnswersCertificationsFree Books & Sample ChaptersTechnical Discussions  Your Account | Advertise with us | Feedback |
Few pages of this site are under construction and we are constantly trying to improve it. If you have any suggestions or ideas about how to improve the site, please Let us know.
Let Spring Manage JSF Beans

Let Spring Manage JSF Beans

                     By Anand K Reddy , developersBOOK.COM , 11/25/2007

The conventional ways of integrating JavaServer Faces and Spring is using the delegating resolver and the other is to the FacesContextUtils.

In this approach of JSF-Spring integration, Inversion of control is applied both by Spring and JSF. The salient point here is that the Spring bean in not injected by Spring, instead the wiring is done by JSF. Here the Spring’s just performed a role of container.


Now the question is, do we need to have the two IOC containers for dependency injection? The answer is yes , but prior to Spring 2.0 release. Now with Spring 2.0 we have the ability for custom scopes . With the help of these custom scopes, we have a better approach for JSF-Spring integration. Using this approach, we will allow Spring to manage our backing bean dependencies. This results in no JSF backing beans in its container.


If you’re already familiar with Spring-JSF integration, you know that JSF has built-in support for dependency injection. You may be wondering why you should bother about Spring managed or JSF managed beans. It’s true that JSF’s support for setter injection is not all that different from that of Spring. But remember that Spring offers more than just simple dependency injection. Spring can bring a lot of value-add to JSF. Spring’s other features (such as declarative transactions, security, remoting, etc.) could come in handy in a JSF application.


In this artice, I’ll show you how Spring manages beans JSF beans. I’m assuming that you are already familiar with JSF. If you are new to JSF or just need a refresher, I recommend that you have a look at JSF tutorial.


The easiest way to understand this approach is to see it in example. In this example we will allow Spring to manage our backing bean dependencies. We will do this by adding the DelegatingVariableResolver and using Spring 2.0 scope support.


This is a simple trading example. Let's start with domain object.


TradeData.java

package com.developersBook.trade.domain;

public class TradeData {
    private long tradeId;
    private String symbol;
    private double price;


    public TradeData() {
        super();
    }


    public TradeData(long tradeId, String symbol, double price) {
        super();
        this.tradeId = tradeId;
        this.symbol = symbol;
        this.price = price;
    }

    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public String getSymbol() {
        return symbol;
    }
    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }
    public long getTradeId() {
        return tradeId;
    }
    public void setTradeId(long tradeId) {
        this.tradeId = tradeId;
    }
}


 

ITradeService.java


package com.developersBook.trade.service;
import com.developersBook.trade.domain.TradeData;
public interface ITradeService {
    public TradeData getTrade(long tradeId);
}

 

TradeServiceImpl.java

package com.developersBook.trade.serviceImpl;
	
import com.developersBook.trade.domain.TradeData;
import com.developersBook.trade.service.ITradeService;
public class TradeServiceImpl implements ITradeService {
    public TradeData getTrade(long tradeId) {
        // Your data access logic
    }
}


Backing bean to get the trade details:

TradeBean.java

package com.developersBook.trade.bean;

import com.developersBook.trade.domain.TradeData;
import com.developersBook.trade.service.ITradeService;

public class TradeBean {
    private long tradeId;
    private ITradeService tradeService;

    public void setTradeService(ITradeService tradeService) {
        this.tradeService = tradeService;
    }
    public long getTradeId() {
        return tradeId;
    }
    public void setTradeId(long tradeId) {
        this.tradeId = tradeId;
    }   


    public TradeData getTradeDetails(long tradeId) {
        return tradeService.getTrade(tradeId);
    }
}




JSF with tradeBean as backing bean.

Trade.jsp  (partial)

<html>
<head>
  <title>Trade.jsp</title>
 </head>
 <body>
  <f:view>
   <h:form>
   <h:panelGrid columns="1">
    <h:outputLabel for="tradeId" />
    <h:inputText id="tradeId" value="#{tradeBean.tradeId}" />
   </h:panelGrid>
   <h:commandButton value="Trade It!!"
             action="#{
tradeBean.getTradeDetails}" />
  </h:form>
  </f:view>
</body>
</html>




Next we need to install the Spring support into the web application. To do this you will create a web context parameter in web.xml.
This tells Spring where to find its applicationContext.xml file, which is used for the Spring's WebApplicationContext.


Spring has a web application listener that reads the contextConfigLocation files (org.springframework.web.context.ContextLoaderListener) and creates the WebApplicationContext for the web application.

Next add the Spring RequestContextListener so that Spring can add the request scope and session scope.





web.xml  (partial)

......

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/applicationContext.xml</param-value> 
</context-param> 


  <listener> 
    <listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class> 
</listener> 


<listener>
  <listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class> 
</listener> 


<servlet>
  <servlet-name>Faces Servlet</servlet-name>
  <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
  <load-on-startup>
0</load-on-startup>
</servlet>


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




If you don't you add RequestContextListener you get the following:

org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'tradeBean':
Scope 'request' is not active for the current thread;
consider defining a scoped proxy for this bean
if you intend to refer to it from a singleton;
nested exception is java.lang.IllegalStateException:
No thread-bound request found:
Are you referring to request attributes outside of an actual web request?
 If you are actually operating within a web request and
still receive this message,your code is probably
running outside of DispatcherServlet/DispatcherPortlet:
 In this case, use RequestContextListener or RequestContextFilter to expose the current request.
Caused by: java.lang.IllegalStateException: No thread-bound request found:
Are you referring to request attributes
outside of an actual web request?
If you are actually operating within a web request and still
receive this message,your code is probably running
outside of DispatcherServlet/DispatcherPortlet:
In this case, use RequestContextListener or
RequestContextFilter to expose the current request.
at org.springframework.web.context.request.RequestContextHolder.
currentRequestAttributes(RequestContextHolder.java:102)


Next add the DelegatingVariableResolver to faces-config.xml

faces-config.xml  (partial)

<faces-config>
<application> 
  <variable-resolver> 
    org.springframework.web.jsf.DelegatingVariableResolver
 </variable-resolver> 
</application> 
</faces-config> 


Inject the TradeBean into the tradeService using the setter method as follows:


applicationContext.xml  (partial)

<beans>
<bean id="tradeService"
class="com.developersBook.trade.service.ITradeService"/>
 <bean id="tradeBean"
class="com.developersBook.trade.bean.TradeBean" scope="request">
       <property name="tradeService" ref="tradeService"/> 
    </bean> 
</beans>


 
HAVE YOUR SAY
At last a quick Ibatis tutorial that works.
Many thanks
Declanmagee, UK
Close
  • Social Web
  • Comments
Name: *
E-Mail: *
Message: *
Confirmation Code:
Enter code: *
(case sensitive)
 

As you can observe faces-config has no managed-beans, instead tradeBean is defined in spring’s application context in request scope.
Now when we click Trade It!! button, we will get the same results, that we would have gotten if JSF managed beans are used.


You can download the source code of this article here.


Back to top

Test

    Add this Article to :
Del.icio.us
Digg
Google
Spurl Slashdot
Y! MyWeb
Blink
Furl
 

  ALSO SEE :

About Us | Our Mission | Terms of use | Author Terms |    Search        | Contact Us | Advertise With Us | Link to Us | Sitemap
Copyright © 2016 developersBOOK.COM. All rights reserved.