del.icio.us Digg DZone Reddit StumbleUpon
Make Web Services Transparent with Spring 2.5 and Apache CXF 2.0 - Willie Wheeler
« Previous | 1 | 2 | 3 | 4 | Next »

Creating the Spring Application Context

This is where all the good stuff is: in the Spring application context.

Spring application context: myapp-servlet.xml

Put this file at /WEB-INF/myapp-servlet.xml so that it's where DispatcherServlet expects to find it. The myapp- part needs to match the value specified for <servlet-name> above. (There's a way to change this but I'm not worried about that for this sample app.)

<?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/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    <!-- Configure CXF to use Aegis data binding instead of JAXB -->
    <bean id="aegisBean"
          class="org.apache.cxf.aegis.databinding.AegisDatabinding"
          scope="prototype"/>
    <bean id="jaxwsAndAegisServiceFactory"
          class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean"
          scope="prototype"> 
        <property name="dataBinding" ref="aegisBean"/>
        <property name="serviceConfigurations">
          <list>
            <bean class="org.apache.cxf.jaxws.support.JaxWsServiceConfiguration"/>
            <bean class="org.apache.cxf.aegis.databinding.AegisServiceConfiguration"/>
            <bean class="org.apache.cxf.service.factory.DefaultServiceConfiguration"/> 
          </list>
        </property>
    </bean>

    <!-- Factory to create the dynamic proxy -->
    <bean id="contactUsFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
        <property name="serviceClass" value="contactus.ContactUsService"/>
        <property name="address"
                  value="http://localhost:8080/cxf-service-example/contactus"/>
        <property name="serviceFactory" ref="jaxwsAndAegisServiceFactory"/>
    </bean>
    
    <!-- Web service dynamic proxy -->
    <bean id="contactUsService"
          class="contactus.ContactUsService"
          factory-bean="contactUsFactory"
          factory-method="create"/>
    
    <!-- Controllers -->
    <bean class="myapp.ViewMessagesController">
        <property name="contactUsService" ref="contactUsService"/>
    </bean>
    
    <!-- View resolvers -->
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

There's lots to talk about here. Let's do it bean-by-bean:

aegisBean: CXF supports different databinding mechanisms (i.e., mechanisms for mapping back and forth between Java and XML). The default is JAXB but I was never able to get that to work for complex data types like contactus.Message. So instead I used Aegis (which is bundled with CXF) and it works great.

jaxwsAndAegisServiceFactory: This factory creates service models either based on a service's WSDL or else based on the structure of the service class. These service models are in turn used by the service proxy factory, which creates your client-side web-service-aware dynamic proxies. Anyway, you don't have to worry too much about jaxwsAndAegisServiceFactory; the only reason we're including it is that we need to be able to tell it to use Aegis databinding.

contactUsFactory: This is a factory that generates the dynamic proxies we've been talking about. These proxies implement the contactus.ContactUsService interface, and this is what gives us the transparency referenced in the title of this article: the client application has no idea that it's working with web services at all (other than in the configuration). If you wanted to, you could collapse the client app and the contactus.ContactUsServiceImpl backend and remove the web service altogether. That's part of the beauty of Spring (and of Java interfaces and dynamic proxies).

We specify not only the service class but also the web service endpoint address and the service factory. Again the only reason we have to deal with the service factory at all is that we're using the non-default Aegis databinding. If you're able to get it working with JAXB then more power to you. (And I'd be interested in hearing about it!)

IMPORTANT: You will need to set the host, port and context path in the address property to match your web service deployment address. The one in the config file is the one I'm using but you're probably using at least a different context path.

The other beans are just Spring MVC beans. Nothing we need to worry about here.

We're now ready to try it out!

Social bookmarks: del.icio.us Digg DZone Reddit StumbleUpon
« Previous | 1 | 2 | 3 | 4 | Next »
Show comments (15)

Post a comment

Your name:
Your e-mail address (won't be displayed):
Your web site (optional):
example: www.xyz.com
Your comment:
Please help us prevent comment spam:

What's New?

2008-10-20 - I've added a new mailing list feature to the site. Sign up to receive e-mail updates about new articles.
2008-09-30 - We've released chapter 4 (User registration) and chapter 5 (Authentication) of Spring in Practice.
2008-09-11 - By popular demand, I've added an RSS feed to the site.
Home | Consulting | Tech Articles | Mailing List | About | Contact | Spring Blog
Copyright © 2008 Wheeler Software, LLC.