Thursday, November 4, 2010

Web Service Client with Spring-WS

Spring-WS fares beautifully at the client-side as well. With its simple API for client side web service, Spring-ws simplifies web service client programming. This post demonstrates how easy it is to develop a web service client using Spring-WS.

WebServiceTemplate, the convenient helper class provided by Spring-WS, provides a set of easy to use helper methods to perform common operations, plus the callback methods for more sophisticated operations, similar to the other familiar Spring template classes.

You may take a quick look at the Spring-WS documentation for an overview and the useful methods that the WebServiceTemplate offers. The usage is straight forward, hence no scope further explanation. 

The ws-client program given here is exactly a Java version of the one developed in the C# language[.Net framework] with the WCF technology, in the part 4 of this series. A client API is developed implementing the (the service interface) as a proxy. Then it is springified in the ApplicationContext.xml, along with the other required components to make the web service wiring. Instead of a Form as in the part 4, here it is a JUnit Testcase, which calls the API. 

Here is the summary of tools and methods used in this program.

IDESpringsource Tool Suite(STS), based on Eclipse (Download from here)    
Transport MechanismHTTP
Message FactorySAAJSoapMessageFactory (SAAJ-specific implementation of WebserviceMessageFactory)
XML Marshaling TechnologyJAXB 2   

Now, let us take a look at the simple steps involved in building a Web Service Client program for our OrderService which was built under the part 2 of this series[WCF client for a Spring Web service: An interoperability story].

  1. Prepare the workspace

    1. Create New Java Project[name:LiveRestautantClient] in STS(Springsource Tool Suite)/Eclipse.

    2. Add all the Spring-ws libraries as dependencies to the project.

    3. Create three source folders, src, test and resource.

    4. Add the project, LiveRestaurant as a project dependency to this project (This step is to reuse the (Java Interface) as the base specification for the OrderServiceClient, which is described below. Alternatively, you can copy just that file and keep locally).

    5. Download Jaxb2 XJC Plugin from and add to the IDE.  
  2. Generate the model(data-types) POJOs from the XSD. (If you have the LiveRestaurant Project, where the web service is built in your work space, you can just add that project to this client project as a dependency, and skip this entire step)

    1. Copy the OrderService.xsd from the LiveRestaurant service project to the resource folder

    2. Right click on the XSD file >> JAXB 2.0 >> Run XJC.

    3. Provide package name:

    4. Output Directory: LiveRestaurantClient\src

    5. Click Finish.

    6. Refresh the project and make sure the classes are generated under src.

  3. Write the client side API, OrderServiceClient as a proxy for the OrderService under the source folder, src, inside package, Here is a sample code that you can reuse. WebServiceTemplate is used here, to invoke the operations.


    import org.apache.log4j.Logger;



    public class OrderServiceClient implements OrderService {

        private static final Logger logger = Logger.getLogger(OrderServiceClient.class);
        private static final ObjectFactory WS_CLIENT_FACTORY = new     ObjectFactory();
        private  WebServiceTemplate webServiceTemplate;

        public OrderServiceClient(WebServiceTemplate webServiceTemplate) {
            this.webServiceTemplate = webServiceTemplate;
        public boolean cancelOrder(String orderRef) {
            logger.debug("Preparing CancelOrderRequest.....");
            CancelOrderRequest request =   WS_CLIENT_FACTORY.createCancelOrderRequest();

            logger.debug("Invoking Web service Operation[CancelOrder]....");
            CancelOrderResponse response = (CancelOrderResponse) webServiceTemplate.marshalSendAndReceive(request);
            logger.debug("Has the order cancelled: " + response.isCancelled());
            return response.isCancelled();

        public String placeOrder(Order order) {
            logger.debug("Preparing PlaceOrderRequest.....");
                    PlaceOrderRequest request = WS_CLIENT_FACTORY.createPlaceOrderRequest();
            logger.debug("Invoking Web service Operation[PlaceOrder]....");
                    PlaceOrderResponse response = (PlaceOrderResponse) webServiceTemplate.marshalSendAndReceive(request);
            logger.debug("Order reference:

    + response.getRefNumber());
            return response.getRefNumber();

  4. Create the Spring ApplicationContext file wiring the components.

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns=""
        xmlns:util="" xmlns:xsi=""
        <bean id="messageFactory" class="">
            <property name="soapVersion">
                <util:constant static-field="" />
        <bean id="orderServiceMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
            <property name="contextPath" value="" />
        <bean id="orderServiceTemplate" class="">
            <constructor-arg ref="messageFactory" />
            <property name="marshaller" ref="orderServiceMarshaller"></property>
            <property name="unmarshaller" ref="orderServiceMarshaller"></property>
            <property name="messageSender">
            <property name="defaultUri" value="http://localhost:8080/LiveRestaurant/spring-ws/OrderService" />
        <bean id="OrderServiceClient" class="">
            <constructor-arg ref="orderServiceTemplate"></constructor-arg>

  5. OrderServiceClientTest - A Junit Testcase, which acts as the client program. It loads the spring ApplicationContext while startup to take hold of the live Spring-WS components. OrderServiceClientTest primarily invokes the client API with some dummy values, and just logs the response.


    import static org.junit.Assert.assertNotNull;
    import static org.junit.Assert.assertTrue;

    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.GregorianCalendar;
    import java.util.List;

    import org.junit.BeforeClass;
    import org.junit.Test;




    public class OrderServiceClientTest {

        private static ClassPathXmlApplicationContext context = null;

        public static void setUpBeforeClass() throws Exception {
            context = new ClassPathXmlApplicationContext("/ApplicationContext.xml");

        public void testCancelOrder() {
            OrderService client = (OrderService) context.getBean("OrderServiceClient");
            boolean cancelled = client.cancelOrder("Ref-2010-9-15-0.8432452204897198");
            assertTrue (cancelled);

        public void testPlaceOrder() {
            OrderService client = (OrderService) context.getBean("OrderServiceClient");
            Order order = prepareDummyOrder();
            String orderRef = client.placeOrder(order);

        private Order prepareDummyOrder() {
            Order order = new Order();
            order.setDateSubmitted(prepareDate(2010, 10, 15, 8, 00, 00));
            order.setOrderDate(prepareDate(2010, 10, 15, 12, 00, 00));
            return order;

        private List<FoodItem> prepareOrderItems() {
            List<FoodItem> items = new ArrayList<FoodItem>(5);
            items.add(prepareFoodItem("Vegetable Thali",

    MEALS, 2));
            items.add(prepareFoodItem("Kheer/ Palpayasam",

    DESSERTS, 4));
            items.add(prepareFoodItem("Fresh Orange Juice",

    JUICES, 1));
            items.add(prepareFoodItem("Fresh Carrot Juice",

    JUICES, 1));
            items.add(prepareFoodItem("Sweet Corn Soup",

    STARTERS, 2));
            return items;

        private XMLGregorianCalendarImpl prepareDate(int year, int month, int date, int hour, int minute, int second) {
            GregorianCalendar calendar = new GregorianCalendar();
            calendar.set(Calendar.YEAR, year);
            calendar.set(Calendar.MONTH, month);
            calendar.set(Calendar.DAY_OF_MONTH, date);
            calendar.set(Calendar.HOUR_OF_DAY, hour);
            calendar.set(Calendar.MINUTE, minute);
            calendar.set(Calendar.SECOND, second);
            return new XMLGregorianCalendarImpl(calendar);

        private FoodItem prepareFoodItem(String name, FoodItemType type,
                double quantity) {
            FoodItem item = new FoodItem();
            return item;

        private Customer prepareCustomer() {
            Customer customer = new Customer();
            customer.setAddressPrimary(prepareAddress("123", "My Office Building",
                    "My Office Street", "Dubai", "United Arab Emirates",
                    "0097150xxxxxxx", "009714xxxxxxx", ""));
            customer.setAddressSecondary(prepareAddress("234", "My Home Building",
                    "My Home Street", "Dubai", "United Arab Emirates",
                    "0097150xxxxxxx", "009714xxxxxxx", ""));
            return customer;

        private Name prepareCustomerName() {
            Name name = new Name();
            return name;

        private Address prepareAddress(String doorNo, String building,
                String street, String city, String country, String phoneMobile,
                String phoneLandline, String email) {
            Address address = new Address();
            return address;

  6.  Finally you will have a package structure like this..

  7. Run the - Right click on the file, Run as --> JUnit Test. (Make sure your web service is running). You should be able to see the success message as given below, if your configurations are correct.

  8. Check your log files or the Console view of your Eclipse (or STS), to see the SOAP message logged, and other debug messages.

Now you have your client program ready with you, hope it was straight forward and easily understandable. You may send in the error messages you may get while developing the program as comments here, along with the stack trace, I will try to find some time to check them out and reply. 

The best part you can see here is that you are not writing any web-service specific code in your program, rather you are just invoking the appropriate method of the WebServiceTemplate. Rest all job is done by the framework (provided you configured the components properly).

The above sample program is just one way of developing a web service client program using Spring Web Services. There are many other approaches you can try with, for example, using a different marshaller, say, XMLBeans. You can even construct your own XML, send via a StreamSource and recieve the response as XML as a StreamResult, then manipulate the XML using XPATH. 

 Besides the default HTTPTransport, you may just try the JMSTransport and the EmailTransport as well. It's all fun :) 

Lets us move on to add some security to our web service and client programs in the next few posts. Expect them soon..


  1. Hi Shameer,
    Thanks for posting the client code. I tried this and I am able to send the Order object to the service side, but for some reason, the return reference is null in the client. Any reason why this could be happening? Appreciate any help.

  2. Basheer,

    Did you use the same code as the server program that I hosted in the Part-2 @ ?

    Did you check the log file/console to see any errors ?

    Did you make sure the server receives the request and then sends the response successfully ?

  3. Basheer,
    Try adding saaj-impl.jar to your server side library.

  4. Hi Shameer,

    Thanks for this valuable article. Meanwhile I was looking into your above article but wouldn't able to find the OrderService class, which is used in orderserviceclient and test. Is it require to be copied from service implementation?


  5. Manish,

    Please see it here.

  6. Manish,

    You either copy the OrderService from the Service project given in the given link, or add the Service Project as a project dependency to this client project. ie, make it is available.

  7. How jaxb Marshaller and unmarsjaller uses generated classes. How to avoid the erorrs like JAXB unmarshalling exception: unexpected element.
    Thank you for your time.

  8. Santha,

    Answer to Q #1.
    Please refer to the ApplicationContext.xml code that is listed above, you can see the marshaller configuration, where the path to the generated classes is given as a property, "contextPath".

    <bean id="orderServiceMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <property name="contextPath" value="" />

    Jaxb2Marshaller can thus get an access to the generated classes(domain classes), bind them to the XML, back and forth.

    Answer to Q #2.
    Make sure the client does not send an invalid(unexpected) XML element to the server. This can be achieved by using a validator that check the XML against the schema.

    If you use the right(version of) libraries to generate the classes and as dependencies to the project, the Jaxb2Marshaller will never produce an invalid XML element out of the generated classes. So, use the right client code.

    It applies the same for server side code too.

  9. Shameer,
    Thank you for an excellent series of articles.
    They are very helpful!

    I am having one problem with some WCF client side code that I am developing. Did you post the client code that you developed in part4 - Building a web service client with WCF. I would like to see what is inside the Reference.cs file.

    Thanks in advance.


  10. Hi Lono,

    Sorry for the delay. You can download the entire client project from

  11. Hi Shameer,

    Do I always have to use Spring WS API for client to access Spring WS Services? This is because we are planning to write Spring Web services that need to be accessed by some clients that are still running on Java 1.4 and these clients will not be updated with Spring libraries.

    Nihil Jose

  12. Nihil,

    All Web Services are supposed to be called by any client who complies the WSDL and additional security if any.

    You can build client programs to access a Spring Webservice using any technology like Apache Axis, JAX-WS, even non-java clients.

    BTW, Spring and Spring Webservices are compatible with JDK 1.4 as well. Only thing is that you cannot use JDK 5+ features such as Annotations, Generics etc.

  13. Hi Shameer,

    Thank you very much for the quick response.

    Nihil Jose

  14. Hi

    Nice Article, i need to develop client where i cannot implement interface of service server side because i have to consume third party already developed service, which may be not provide there interface. Please need help in this regard.


  15. @Waqas,

    You can achieve this by one of many options, including via the method,
    webServiceTemplate. sendSourceAndReceiveToResult(Source requestPayload, Result responseResult);

    The one given above will allow you to send request and response purely in XML format, so that do not need to use a marshaling technology.

    See the example given here -

    You can still use an object-xml-marshaller(OXM) even if you do not have the service interface with you. See the example here..

  16. Dear Shameer,

    Thanks alot for your response. these link are very useful. but my limitation are that i have develop client use marshaling and unmarshaling with caster only in spring. so is there any exact example or article related to it, which can guide me to do that. Than please guide me to it, as I m very new to web service in spring. Thanks in advance


  17. Hello Shameer,

    now it's client's turn to give errors...

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderServiceTemplate' defined in class path resource [ApplicationContext.xml]: Cannot create inner bean '' of type [] while setting bean property 'messageSender'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '' defined in class path resource [ApplicationContext.xml]: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/apache/commons/httpclient/HttpConnectionManager

    could not figure out what's going wrong..
    please guide..

  18. Ravi,

    Make sure you have commons-httpclient-xx.jar in your project classpath. If configured with eclipse, Project Properties --> Java Build Path --> Libraries --> Add jars --> browse and add --> OK --> Rebuild, Redeploy.

  19. Hello Shameer,

    now it's coming Not Found [404]

    I have spring-ws.core-2.5.6.jar in my classpath.

  20. Looks like problem withe the URL, what is it ?

  21. The URL is


    but getting new errors after adding some jars I/O error: Connection refused: connect; nested exception is Connection refused: connect

  22. Hello Shameer,

    now the error is like, JAXB unmarshalling exception: unexpected element (uri:"http://localhost:8080/OrderService/schema", local:"cancelOrderRequest"). Expected elements are <{}cancelOrderRequest>,<{}cancelOrderResponse>,<{}placeOrderRequest>,<{}placeOrderResponse>; nested exception is javax.xml.bind.UnmarshalException: unexpected element (uri:"http://localhost:8080/OrderService/schema", local:"cancelOrderRequest"). Expected elements are <{}cancelOrderRequest>,<{}cancelOrderResponse>,<{}placeOrderRequest>,<{}placeOrderResponse>
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.internal.runners.TestMethod.invoke(
    at org.junit.internal.runners.MethodRoadie.runTestMethod(
    at org.junit.internal.runners.MethodRoadie$
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(
    at org.junit.internal.runners.MethodRoadie.runTest(
    at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(
    at org.junit.internal.runners.JUnit4ClassRunner.runMethods(
    at org.junit.internal.runners.JUnit4ClassRunner$
    at org.junit.internal.runners.ClassRoadie.runUnprotected(
    at org.junit.internal.runners.ClassRoadie.runProtected(
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(

    everywhere i'm using http://localhost:8080/OrderService/schema..
    now where this jar came to know that it needs

    do guide..

  23. Hi. Shameer.

    I run both LiveRestaurant and LiveRestaurantClient Application and generated wsdl and run client application it not view any output. but How can I see the logs or output. I did it in eclipse.

    Please guide me. I am new to spring and webservices.
    Adavance thanks.


  24. Hello Shameer...
    some how I managed to turned green light on.

    I had old java files with wrong namespace in the service project.

    Thanks for your support....
    will explore your blog and ping you a lot...:D

  25. Laxman,

    You may configure Log4J for the service app, and set the log level to debug, then you can see the MessageDispatcher logs the incoming SOAP request and the outgoing SOAP response.

    Easy way to configure Log4J, is these four steps.
    1) Add log4j jar file into your classpath/project
    2) Add a context-param in the web.xml, name = log4jConfigLocation, value = /WEB-INF/
    3) Add a file into the WEB-INF folder
    4) Add property,
    in the

    Rebuild, redeploy the app, run the client program again, you should see the message in the console, among other spring debug messages.

  26. Hello Shamer,

    Thank you very much for an easy to follow tutorial. I got the sample working but when I try the same with my project, I see the wsdl published.. when I run the client i get 404, Please help me fix the issue.

    Please let me know what information needed.

    Thanks in advance.


  27. @Lokesh,

    It looks like a URL problem, can you check if the URL follows the pattern, http://<ip-address>:<port>/<context-root>/spring-ws/<Service-Name> ?

    a sample URL is --


  28. Thanks shameer, it has something to do with URL, your pointers in that direction worked. Also, implemented security for the the same. Now I am trying to use an AXIS2 client to access the service.... it works fine without security, with security I have no idea how to add the security header in the request from AXIS2 client, please help.

    Thanks in advance.

  29. Hi Shameer,
    Thanks for the great tutorials. Can you also provide pointers/code to call the actual Endpoint from the client; a main() method may be.

    Thanks again.

  30. Shameer,
    Is there a way i can retrieve the request SOAP xml using Unmarshaller may be. It requires a Source object and i am not what that is.

  31. I am getting the below error. Pls give me the resolution. Not Found [404]

  32. Hi Shameer,

    Thanks for the great tutorial. I am learning spring by reading your blog. While using your code I getting this error.

    Following import statement can not be resolved


    I expect all spring related jar should be included in STS IDE. Do I need to include any jar in lib folder?

    Please help.

  33. Hi All,

    This article is great. But I am facing a problem because I have two different namespaces. My schema and definition are kept in different namespaces.
    For that I have defined my marshaller as follows using the property
    contextPaths in the applicationContext.xml: specifying the two paths of the java packages generated by JAXB.

    Yet, my marshaller gives me bind exception." missing an @XmlRootElement annotation" .

    Can anyone please help me on this ?

    Thanks in advance.
    In the As a result my marshaller is failing. Gives me @XmlRootElement

  34. Many have requested for the classpath dependencies for the project. Here are the jar files I have added into the classpath, for the service project. Most of them are available from the Spring download(with dependencies) archive.


  35. hi and thanks for this great tutorial.

    i'm facing an issue here. i get:
    - "org.xml.sax.SAXParseException: XML document structures must start and end within the same entity" when using SaajSoapMessageFactory
    - " com.ctc.wstx.exc.WstxEOFException: Unexpected EOF; was expecting a close tag for element" when using AxiomSoapMessageFactory

    unfortunately i can't put my hands on the server side.
    i was basically just asked to build a client for this wsdl.

    any help will be much appreciated

  36. Hi, thanks for tutorial:

    i am getting java.lang.ClassCastException: javax.xml.bind.JAXBElement cannot be cast
    any idea about why i am getting this error

  37. thanks Sameer for the tutorial.I have got the app working except for test case which is failing.I am not getting the response, but i am able to set request.Pls help

    1. hi, thanks for this tutorial,
      Please I need to implement a client program that interact with Open Travel Alliance (OTA)"I mean I need to send requests to a GDS(Global Distribution Service) via OTA " but I am such a beginner that I am confused and I don't know what to do, can you please give me some steps to follow
      any suggestions are extremely appreciated.

  38. Hi Sameer,

    we have implemented the service and client example and could get the wsdl. But when invoking the service from the client the end point is getting null instead of marshalled request object. Can you please throw some light where exactly we need to correct.

    1. Is your server console or lg file shows any trace or error message of the client call ?

  39. Hi Sameer ,

    There are no errors in the server console ,and no exception was found,please find the below lines of log where you can find the null order object.Kindly revert incase of any further information.

    18:00:57,544 INFO [STDOUT] 18:00:57,544 INFO [MessageDispatcherServlet] Servlet 'spring-ws' configured successfully
    18:00:58,247 INFO [STDOUT] 18:00:58,247 INFO [OrderServiceImpl] Order has been cancelled with Reference : null
    18:00:58,388 INFO [STDOUT] 18:00:58,388 INFO [OrderServiceImpl] Order has been placed. Order Info is :

  40. Hi Rajesh,

    I have faced the similar issue while developing java client for the .Net webservice and have added below lines then it got rid of my problem, i hope it will help u.

    SoapActionCallback soapActionCallback = new SoapActionCallback ("http://uri/contextpath(or)ServiceName/Operation");
    SomeResponse getResponse = (SomeResponse)webServiceTemplate.marshalSendAndReceive(reqObj, soapActionCallback);


  41. hi, i managed to setup the client. but when i run the as junit, im getting log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
    log4j:WARN Please initialize the log4j system properly.
    log4j:WARN See for more info.

    where did i go wrong?

  42. @Christopher, this is just a Log4J warning, you can configure Log4j in your app by just adding a or xml file, it really helps to find out the problems in your code.