Tag Archives: web service

Webservice Client using Spring-WS – A UML perspective

A picture is worth thousand words. The following is the UML diagram that shows the classes involved for developing webservice client code using Spring-WS.

References:

Spring Web Services – Reference Documentation

Spring IN ACTION

UML Diagram created using Visual Paradigm for UML Community Edition

WebService Client Target NameSpace clash

When handling multiple web services, you may have encountered scenarios where two web services declare schema definition under same namespace. Having multiple elements defined under same name space is not a problem. But, defining a same element with different structure under same namespace but in different web service can create problem.

This situation can happen when there is no global repository for the schema definitions in a company. I will explain the situation in more detail.

Consider a company XYZ with web address http://www.xyz.com. The company has two enterprise applications A and B. The application A decides to expose business function as web services. Two different teams 1 and 2 in application A are working on building the web service.

Both the team use the same target namespace http://www.xyz.org/appA/.

Team 1 builds an web service WS-1. They create a element NewOperation.

The schema of the element NewOperation and part of the wsdl definition is listed below


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.xyz.org/appA/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="NewWSDLFile" targetNamespace="http://www.xyz.org/appA/">
  <wsdl:types>
    <xsd:schema targetNamespace="http://www.xyz.org/appA/">
      <xsd:element name="NewOperation">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="in" type="xsd:string"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
   </wsdl:types>

Team 2 also builds an web service WS-2. They also create a element NewOperation.

The schema of the element NewOperation and part of the wsdl definition is listed below


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.xyz.org/appA/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="NewWSDLFile" targetNamespace="http://www.xyz.org/appA/">
  <wsdl:types>
    <xsd:schema targetNamespace="http://www.xyz.org/appA/">
      <xsd:element name="NewOperation">
        <xsd:complexType>
          <xsd:sequence>
              <xsd:element name="in" type="xsd:string" />
              <xsd:element name="in_1" type="xsd:string"></xsd:element>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
   </wsdl:types>

As you can see both the elements have the same name, but have different structure which is an not a good design. Since, both the team do not interact with other, they have failed to identify the flaw. Both, the team build server implementation of their web service and deploy each as EAR independent of the other. Both the teams do not face any issue, since both the server implementations are deployed independently.

Now, team in application B decides to use the web services provided by application A. They build client implementations for both the web services provided by A using standard build tools (clientgen from Weblogic). The build tools usually generate the java files (in a jar) binding the schema elements to classes created in the reverse namespace package (i.e., org.xyz.www.appA). They put the client jars of both the web service in the same classpath of the application B.

When they try to use the operations provided by the web service, they face exception related to serialization or deserialization whenever an operation involving the element NewOperation is involved. The exception can happen in either the WS-1 or WS-2 web service. This is because, a wrong class is used in the web service. As per java classpath rule, whenever NewOperation class needs to be loaded it finds only one version of the class depending on which client jar appears first. The other NewOperation class is never found by the application.

In order to resolve the issue, the team A needs to move the definition of the element NewOperation in one of the web service to a different target namespace. But this is a costly option, since WS-1 and WS-2 are already implemented and will require changes in the server implementation and also for all the clients using the web service.

The other option is for the client to use options provided in the build tools to generate class binding the schema definition in different package other than that generated by default for one of the web service.

This can done in Weblogic tool clientgen by adding the option typePackageName. Note the additional attribute typePackageName in the ant build script.


<clientgen wsdl="http://example.com/myapp/myservice.wsdl"
           packageName="myapp.myservice.client"
           clientJar="myapps/myService_client.jar"
       typePackageName="com.appB"
/>

Also the same can be done in Eclipse by checking the “Define custom mapping for namespace to package” option and defining the custom mapping when generating the client implementation of the web service.

This avoids the clash as the client implementations are generated under different package.

This problem needs to be avoided in first place when creating the web service. Each company needs to have a central repository where all the schema definitions are available to avoid duplication of element name under same target namespace.

Reblog this post [with Zemanta]

Using TCP/IP Monitor with Weblogic Webservice Clients

TCP/IP Monitor is an excellent eclipse plugin to monitor TCP/IP or HTTP traffic. In this scenario, i have used this plugin to analyze the SOAP messages that are exchanged between the webservice client and server developed using Weblogic tools.

TCP/IP Monitor is a proxy server that monitors for all traffic flowing through. In case, you want to monitor the traffic between two network nodes, you will have to use TCP/IP Monitor as proxy server so that it can monitor the traffic flowing between the endpoints.

Initially setup the TCP/IP Monitor using Preferences window in Eclipse. Create a new monitor by specifying the local monitoring port(which will the port number of the TCP/IP Monitor proxy server), host name(host name of the webservice server), port(port number of the webservice server port) and type(select HTTP or TCP/IP). After the new monitor is defined start the monitor.

Modify the Weblogic webservice client code to use the TCP/IP Monitor proxy server. This is done by the following piece of code. This code needs to be executed before client webservice port creation.


        System.setProperty("http.proxyHost", "localhost");
        System.setProperty("http.proxyPort", "80");
        System.setProperty("weblogic.webservice.transport.http.proxy.host", "localhost");
        System.setProperty("weblogic.webservice.transport.http.proxy.port", "80");

The port specified will have to be same as the one of the TCP/IP Monitor created to monitor the webservice.

On invocation of the webservice client, you will be able to see the data exchanged between the client and the server in the TCP/IP Monitor view. It shows the SOAP messages exchanged.

TCP/IP Monitor is an excellent tool to analyze the SOAP messages exchanged in webservice invocations.

The TCP/IP Monitor plugin is part of standard Eclipse distribution for J2EE developers.

Useful Links

To search documentation on TCP/IP Monitor

http://help.eclipse.org/ganymede/index.jsp

Using proxy for Weblogic webservice client

http://edocs.bea.com/wls/docs81/webserv/client.html#1077879