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 OrderService.java (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 OrderService.java (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         https://jaxb-workshop.dev.java.net/servlets/ProjectDocumentList?folderID=4962&expandFolder=4962&folderID=4962 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: com.live.order.domain

    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, com.live.order.service.client. Here is a sample code that you can reuse. WebServiceTemplate is used here, to invoke the operations.


    package com.live.order.service.client;

    import org.apache.log4j.Logger;

    import org.springframework.ws.client.core.WebServiceTemplate;

    import com.live.order.domain.CancelOrderRequest;
    import com.live.order.domain.CancelOrderResponse;
    import com.live.order.domain.ObjectFactory;
    import com.live.order.domain.Order;
    import com.live.order.domain.PlaceOrderRequest;
    import com.live.order.domain.PlaceOrderResponse;
    import com.live.order.service.OrderService;

    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;
        }
               
        @Override
        public boolean cancelOrder(String orderRef) {
            logger.debug("Preparing CancelOrderRequest.....");
            CancelOrderRequest request =   WS_CLIENT_FACTORY.createCancelOrderRequest();
            request.setRefNumber(orderRef);

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

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

    "
    + response.getRefNumber());
            return response.getRefNumber();
        }
    }   
    OrderServiceClient.java


  4. Create the Spring ApplicationContext file wiring the components.



    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
            http://www.springframework.org/schema/util
            http://www.springframework.org/schema/util/spring-util-2.0.xsd">
           
        <bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
            <property name="soapVersion">
                <util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_11" />
            </property>
        </bean>
           
        <bean id="orderServiceMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
            <property name="contextPath" value="com.live.order.domain" />
        </bean>
       
        <bean id="orderServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
            <constructor-arg ref="messageFactory" />
            <property name="marshaller" ref="orderServiceMarshaller"></property>
            <property name="unmarshaller" ref="orderServiceMarshaller"></property>
            <property name="messageSender">
                <bean
                    class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
                </bean>
            </property>
            <property name="defaultUri" value="http://localhost:8080/LiveRestaurant/spring-ws/OrderService" />
        </bean>
       
        <bean id="OrderServiceClient" class="com.live.order.service.client.OrderServiceClient">
            <constructor-arg ref="orderServiceTemplate"></constructor-arg>
        </bean>
    </beans>
    ApplicationContext.xml


  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.


    package com.live.order.service.client.test;

    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;

    import org.springframework.context.support.ClassPathXmlApplicationContext;

    import com.live.order.domain.Address;
    import com.live.order.domain.Customer;
    import com.live.order.domain.FoodItem;
    import com.live.order.domain.FoodItemType;
    import com.live.order.domain.Name;
    import com.live.order.domain.Order;
    import com.live.order.service.OrderService;

    import com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl;

    public class OrderServiceClientTest {

        private static ClassPathXmlApplicationContext context = null;

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

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

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

        private Order prepareDummyOrder() {
            Order order = new Order();
            order.setCustomer(prepareCustomer());
            order.setDateSubmitted(prepareDate(2010, 10, 15, 8, 00, 00));
            order.setOrderDate(prepareDate(2010, 10, 15, 12, 00, 00));
            order.getItems().addAll(prepareOrderItems());
            return order;
        }

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

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

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

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

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

    FoodItemType.
    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();
            item.setName(name);
            item.setType(type);
            item.setQuantity(quantity);
            return item;
        }

        private Customer prepareCustomer() {
            Customer customer = new Customer();
            customer.setName(prepareCustomerName());
            customer.setAddressPrimary(prepareAddress("123", "My Office Building",
                    "My Office Street", "Dubai", "United Arab Emirates",
                    "0097150xxxxxxx", "009714xxxxxxx", "shameer@mycompany.com"));
            customer.setAddressSecondary(prepareAddress("234", "My Home Building",
                    "My Home Street", "Dubai", "United Arab Emirates",
                    "0097150xxxxxxx", "009714xxxxxxx", "shameer@myhome.com"));
            return customer;
        }

        private Name prepareCustomerName() {
           
            Name name = new Name();
            name.setLName("Shameer");
            name.setFName("Kunjumohamed");
            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();
            address.setDoorNo(doorNo);
            address.setBuilding(building);
            address.setStreet(street);
            address.setCity(city);
            address.setCountry(country);
            address.setPhoneMobile(phoneMobile);
            address.setPhoneLandLine(phoneLandline);
            address.setEmail(email);
            return address;
        }
    }
    OrderServiceClientTest.java



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




  7. Run the OrderServiceClientTest.java - 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..


51 comments:

  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.
    Thanks,
    Basheer.

    ReplyDelete
  2. Basheer,

    Did you use the same code as the server program that I hosted in the Part-2 @ http://justcompiled.blogspot.com/2010/09/building-web-service-with-spring-ws.html ?

    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 ?

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

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

    Thanks
    Manish

    ReplyDelete
  5. Manish,

    Please see it here.
    http://justcompiled.blogspot.com/2010/09/building-web-service-with-spring-ws.html

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

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

    ReplyDelete
  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="com.live.order.domain" />
    </bean>

    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.

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

    Regards,
    --CJ

    ReplyDelete
  10. Hi Lono,

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

    http://cid-4498153a7d374441.office.live.com/browse.aspx/JustCompiled

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

    Regards,
    Nihil Jose

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

    ReplyDelete
  13. Hi Shameer,

    Thank you very much for the quick response.

    Regards,
    Nihil Jose

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

    Regards
    Waqas

    ReplyDelete
  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 - http://static.springsource.org/spring-ws/sites/1.5/reference/html/client.html#d0e3378

    You can still use an object-xml-marshaller(OXM) even if you do not have the service interface with you. See the example here..
    http://static.springsource.org/spring-ws/sites/1.5/reference/html/oxm.html#oxm-usage

    ReplyDelete
  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

    Regards
    Waqas

    ReplyDelete
  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 'org.springframework.ws.transport.http.CommonsHttpMessageSender#1d64c37' of type [org.springframework.ws.transport.http.CommonsHttpMessageSender] while setting bean property 'messageSender'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.ws.transport.http.CommonsHttpMessageSender#1d64c37' 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..

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

    ReplyDelete
  19. Hello Shameer,

    now it's coming

    org.springframework.ws.client.WebServiceTransportException: Not Found [404]


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

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

    ReplyDelete
  21. The URL is

    http://localhost:8080/LiveRestaurant/spring-ws/OrderService

    but getting new errors after adding some jars

    org.springframework.ws.client.WebServiceIOException: I/O error: Connection refused: connect; nested exception is java.net.ConnectException: Connection refused: connect

    ReplyDelete
  22. Hello Shameer,

    now the error is like,


    org.springframework.ws.soap.client.SoapFaultClientException: JAXB unmarshalling exception: unexpected element (uri:"http://localhost:8080/OrderService/schema", local:"cancelOrderRequest"). Expected elements are <{http://www.liverestaurant.com/OrderService/schema}cancelOrderRequest>,<{http://www.liverestaurant.com/OrderService/schema}cancelOrderResponse>,<{http://www.liverestaurant.com/OrderService/schema}placeOrderRequest>,<{http://www.liverestaurant.com/OrderService/schema}placeOrderResponse>; nested exception is javax.xml.bind.UnmarshalException: unexpected element (uri:"http://localhost:8080/OrderService/schema", local:"cancelOrderRequest"). Expected elements are <{http://www.liverestaurant.com/OrderService/schema}cancelOrderRequest>,<{http://www.liverestaurant.com/OrderService/schema}cancelOrderResponse>,<{http://www.liverestaurant.com/OrderService/schema}placeOrderRequest>,<{http://www.liverestaurant.com/OrderService/schema}placeOrderResponse>
    at org.springframework.ws.soap.client.core.SoapFaultMessageResolver.resolveFault(SoapFaultMessageResolver.java:37)
    at org.springframework.ws.client.core.WebServiceTemplate.handleFault(WebServiceTemplate.java:699)
    at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:527)
    at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:465)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:314)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:308)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:300)
    at com.live.order.service.client.OrderServiceClient.cancelOrder(OrderServiceClient.java:33)
    at com.live.order.service.client.test.OrderServiceClientTest.testCancelOrder(OrderServiceClientTest.java:38)
    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(TestMethod.java:59)
    at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
    at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
    at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
    at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
    at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
    at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

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


    do guide..

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

    Regards
    Laxman

    ReplyDelete
  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

    ReplyDelete
  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/log4j.properties
    3) Add a log4j.properties file into the WEB-INF folder
    4) Add property, log4j.logger.org.springframework=DEBUG
    in the lof4j.properties

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

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

    Lokesh

    ReplyDelete
  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 --
    http://localhost:8080/LiveRestaurant/spring-ws/OrderService

    ??

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

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

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

    ReplyDelete
  31. I am getting the below error. Pls give me the resolution.
    org.springframework.ws.client.WebServiceTransportException: Not Found [404]

    ReplyDelete
  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

    import org.springframework.context.support.ClassPathXmlApplicationContext;

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

    Please help.

    ReplyDelete
  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.
    Priyanka
    In the As a result my marshaller is failing. Gives me @XmlRootElement

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


    aopalliance-1.0.jar
    commons-logging-1.1.1.jar
    log4j-1.2.9.jar
    spring-aop-3.0.5.RELEASE.jar
    spring-asm-3.0.5.RELEASE.jar
    spring-beans-3.0.5.RELEASE.jar
    spring-context-3.0.5.RELEASE.jar
    spring-context-support-3.0.5.RELEASE.jar
    spring-core-3.0.5.RELEASE.jar
    spring-expression-3.0.5.RELEASE.jar
    spring-oxm-3.0.5.RELEASE.jar
    spring-web-3.0.5.RELEASE.jar
    spring-webmvc-3.0.5.RELEASE.jar
    spring-ws-core-2.0.1.RELEASE.jar
    spring-xml-2.0.1.RELEASE.jar
    wsdl4j-1.6.1.jar

    ReplyDelete
  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
    - "org.apache.axiom.om.OMException: 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

    ReplyDelete
  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

    ReplyDelete
  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

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

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

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

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

    ReplyDelete
  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);

    Thanks,
    Gangadhar

    ReplyDelete
  41. hi, i managed to setup the client. but when i run the OrderServiceClientTest.java 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 http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

    where did i go wrong?

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

    ReplyDelete
  43. Hi Shameer,

    When I am trying to deploy my war file into dev server and hitting url, I am getting proper response. Same war trying to add in local. I am getting org.jboss.ws.core.soap.SOAPContentElement - transitionTo:137 Transitioning from XML_VALID to DOM_VALID, com.xxx.xxxx.xxxxx.xxx.xxx- xxx:31 Input validation error

    ReplyDelete
  44. Was looking for this only to implement in my project.
    Thanks a ton.
    Thanks again.

    ReplyDelete
  45. Was looking for this only to implement in my project.
    Thanks a ton.
    Thanks again.

    ReplyDelete
  46. Hi Shameer
    I am new to WebServices. I have followed both the blogs
    a) http://justcompiled.blogspot.com/2010/09/building-web-service-with-spring-ws.html
    b) http://justcompiled.blogspot.com/2010/11/web-service-client-with-spring-ws.html

    My WebService is deployedon Tomcat 7.0.33 and I can view the wsdl file using URL: http://localhost:8080/liverestaurant/spring-ws/OrderService.wsdl

    But when I try to run the OrderServiceClientTest.java for testPlaceOrder(), I am getting

    org.springframework.ws.client.WebServiceTransportException: Not Found [404]

    on LiveRestaurant/spring-ws/OrderService

    My placeOrderRequest from OrderServicePayloadRootAnnotationEndPoint.java looks as follows:

    @PayloadRoot(localPart = "placeOrderRequest", namespace = "http://www.liverestaurant.com/OrderService/schema")
    public JAXBElement getOrder(PlaceOrderRequest placeOrderRequest) {
    PlaceOrderResponse response = JAXB_OBJECT_FACTORY.createPlaceOrderResponse();
    response.setRefNumber(orderService.placeOrder(placeOrderRequest.getOrder()));

    return new JAXBElement(new QName("http://www.liverestaurant.com/OrderService/schema",
    "placeOrderResponse"), PlaceOrderResponse.class, response);
    }

    Please advice.

    ReplyDelete
  47. Hi Shameer
    I am new to WebServices. I have followed both the blogs
    a) http://justcompiled.blogspot.com/2010/09/building-web-service-with-spring-ws.html
    b) http://justcompiled.blogspot.com/2010/11/web-service-client-with-spring-ws.html

    My WebService is deployedon Tomcat 7.0.33 and I can view the wsdl file using URL: http://localhost:8080/liverestaurant/spring-ws/OrderService.wsdl

    But when I try to run the OrderServiceClientTest.java for testPlaceOrder(), I am getting

    org.springframework.ws.client.WebServiceTransportException: Not Found [404]

    on LiveRestaurant/spring-ws/OrderService

    My placeOrderRequest from OrderServicePayloadRootAnnotationEndPoint.java looks as follows:

    @PayloadRoot(localPart = "placeOrderRequest", namespace = "http://www.liverestaurant.com/OrderService/schema")
    public JAXBElement getOrder(PlaceOrderRequest placeOrderRequest) {
    PlaceOrderResponse response = JAXB_OBJECT_FACTORY.createPlaceOrderResponse();
    response.setRefNumber(orderService.placeOrder(placeOrderRequest.getOrder()));

    return new JAXBElement(new QName("http://www.liverestaurant.com/OrderService/schema",
    "placeOrderResponse"), PlaceOrderResponse.class, response);
    }

    Please advice.

    ReplyDelete