Photo by tanakawho - http://www.flickr.com/photos/28481088@N00/193379346/
del.icio.us Digg DZone Reddit StumbleUpon
1 | 2 | 3 | 4 | Next »
Software Development

Make Web Services Transparent with Spring 2.5 and Apache CXF 2.0

Write web service clients that don't know they're web service clients using Spring and CXF.

In our previous installment, we showed how to create Java-first web services in Spring 2.5 using Apache CXF 2.0. This time we're going to show how to consume web services, once again using Spring 2.5 and Apache CXF 2.0.

Something great about the Spring/CXF duo is that your web service clients don't know that they're web service clients. The approach is simple: as in any Spring app, you define Java interfaces for your services and inject the service implementations into the client classes that use them (such as MVC controllers). CXF allows you to generate dynamic proxies according to the same Java service contract—the proxies are just another service implementation—and hence your client classes have no idea that they're calling web services.

This article shows you what you need to do to get it to work. If you haven't already done so, please see the previous article, Web Services with Spring 2.5 and Apache CXF 2.0, to get your web services set up. That article describes a user comment service that I build upon in the current article.

Project Setup

First we need to set up the web service client project. Here are the various dependencies involved.

Spring 2.5

These all come from the Spring 2.5 distribution. You can use whatever Spring 2.5 libraries you need for your own app. Here I just happen to be using Spring MVC and JSTL, though neither of those is required for Spring/CXF integration.

  • jstl.jar (in lib/j2ee)
  • spring.jar
  • spring-mvc.jar (in dist/modules; the sample app uses Spring MVC)
  • standard.jar (in lib/jakarta-taglibs; this is the JSTL reference implementation)

CXF and dependencies

You can get these from the CXF 2.0.4 distribution. Whether all of these are really necessary I don't know—for example I'm not sure why we need the JavaMail library—but I'm just going by what the CXF user manual says.

  • commons-logging-1.1.jar
  • cxf-2.0.4-incubator.jar (this is the main CXF JAR)
  • geronimo-activation_1.1_spec-1.0-M1.jar (or Sun's Activation jar)
  • geronimo-annotation_1.0_spec-1.1.jar (JSR 250)
  • geronimo-javamail_1.4_spec-1.0-M1.jar (or Sun's JavaMail jar)
  • geronimo-servlet_2.5_spec-1.1-M1.jar (or Sun's Servlet jar)
  • geronimo-stax-api_1.0_spec-1.0.jar
  • geronimo-ws-metadata_2.0_spec-1.1.1.jar (JSR 181)
  • jaxb-api-2.0.jar
  • jaxb-impl-2.0.5.jar
  • jaxws-api-2.0.jar
  • neethi-2.0.2.jar
  • saaj-api-1.3.jar
  • saaj-impl-1.3.jar
  • wsdl4j-1.6.1.jar
  • wstx-asl-3.2.1.jar
  • XmlSchema-1.3.2.jar
  • xml-resolver-1.2.jar

Aegis dependencies

In addition to the above, you will need to add jdom-1.0.jar since Aegis databinding uses it.

Client library dependencies

In the previous article we created three classes in the contactus package: ContactUsService, ContactUsServiceImpl, and Message. You will need to JAR ContactUsService (which is a service interface) and Message (which is a domain model class) and add the JAR as a dependency for the client application. You do not need to include ContactUsServiceImpl since that's the backend for the web service; it's not part of the interface. On the client side we will see that CXF will create a web service proxy according to the ContactUsService interface, and it will use Message for marshalling and unmarshalling.

With the dependencies in place, we'll now create a simple client that can view user messages using the web service we created the last time. We're not going to treat the "post user message" operation in this article though it works in exactly the same way (which is why we're not going to treat it).

Social bookmarks: del.icio.us Digg DZone Reddit StumbleUpon
1 | 2 | 3 | 4 | Next »

Comments (11)

Good stuff. Did you ever get JAXB working?
By dj on Mar 14, 2008 at 11:09 AM PDT
Thanks DJ. Nope, though I didn't try after I wrote the article. JAXB worked fine as long as I stuck with simple data types. You can try it yourself by just removing the serviceFactory injection from the contactUsFactory in myapp-servlet.xml. Maybe you'll have better luck than I did. If so I'd be interested to hear.
By Willie Wheeler on Mar 14, 2008 at 10:36 PM PDT
Is there a URL that I can get your example source code?
Thanks!
By XML on Mar 21, 2008 at 5:34 AM PDT
Hi XML. I added the source code for the services and client app to the Resources section at the end of the article. I did not include the third-party JARs since those mostly come from the CXF distribution itself.
By Willie Wheeler on Mar 21, 2008 at 11:28 PM PDT
Tried the tutorial, it works great as is
1. except the one JAR file as JDOM1.0.Jar needs to be added as mentioned in your earlier tutorial.
2. JSP file does not print anything, but I am getting the output in Console.
${message.lastNameFirstName} (${message.email}): ${message.text}
By Mark on Apr 4, 2008 at 1:06 PM PDT
It works with Spring 2.5.2 using JBoss 4.3 CXF stack (not with the default included 2.0.4, but with 2.0.5).
By Marek Lange on Apr 9, 2008 at 2:17 AM PDT
I cant get the client to work with spring 2.5.x, there is a very annoying bug for me:

java.lang.NoSuchMethodError: setConfigLocation
org.springframework.web.servlet.FrameworkServlet.c reateWebApplicationContext(FrameworkServlet.java:3 98)....

I changed the client for spring 2.0.x and it works.
By Isaias on May 8, 2008 at 7:53 AM PDT
Not sure exactly what you're running into but the API changes from time to time. The setConfigLocation() method appears in Spring 2.5.2; compare the Spring 2.5.1 API

http://static.springframework.org/spring/docs/2.5.1/api/org/springframework/web/context/ConfigurableWebApplicationContext.html

with the Spring 2.5.2 API

http://static.springframework.org/spring/docs/2.5.2/api/org/springframework/web/context/ConfigurableWebApplicationContext.html

When I wrote the article I was using the Spring 2.5.0 distribution. If you aren't already doing so I would try using the latest versions of Spring and CXF and see if you have any luck. Sounds like you aren't the only one who's had this issue though:

http://forum.springframework.org/showthread.php?p=179390
By Willie Wheeler on May 9, 2008 at 8:43 PM PDT
Hi, I'm beginner and I have a problem with client :(
I use tomcat 6.0.x, spring 2.5.4 and CXF 2.1

org.apache.cxf.binding.soap.SoapFault: Error reading XMLStreamReader.
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:70)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:35)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:221)
..........
..........
Thanks for help
By Petross on May 15, 2008 at 5:53 PM PDT
how to access a webservice from another webservice
By kiran on Sep 2, 2008 at 4:51 AM PDT
Thanks for the article! I created a maven build so that folks can run (and change) the code instantly. See: http://www.jroller.com/brodkin/entry/a_maven_project_for_willie
By Sam Brodkin on Sep 3, 2008 at 5:44 AM PDT
Post a comment
Home | Consulting | Articles | Blog | About | Contact
Copyright © 2008 Wheeler Software, LLC.