Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Complex datatypes in SOAP-based web services

Using Apache Axis, Apache SOAP, and TestMaker

Frank Cohen, CEO, PushToTest
Frank Cohen is the "go to" guy when enterprises need to test and solve problems in complex interoperating information systems, especially Web services. Frank is Founder of PushToTest, a test automation solutions business and author of several books on testing information systems. For the past 20 years he led some of the software industry's most successful products, including Norton Utilities for the Macintosh, Stacker, and SoftWindows. He began by writing operating systems for microcomputers, helping establish video games as an industry, helping establish the Norton Utilities franchise, leading Apple's efforts into middleware and Internet technologies, and most recently serving as principal architect for the Sun Community Server, Inclusion.net (OTC: IINC), and TuneUp.com. He serves as an active member and past board member of the Software Developers Forum, the leading computer software industry association in the Silicon Valley of California. You can reach Frank at fcohen at pushtotest.com.

Summary:  The IBM Emerging Technologies Toolkit (ETTK) features the Axis toolkit for software developers to enable Java applications as SOAP-based web services. In this article, Frank Cohen shows Java developers how to use Axis to work with complex datatypes, including JavaBean components.

Date:  26 May 2003
Level:  Advanced
Also available in:   Japanese

Activity:  2450 views
Comments:  

The ETTK is a kit of tools and libraries for designing, developing, and executing emerging autonomic and Grid-related technologies and web services. While the ETTK comes with examples that showcase recently announced specifications and prototypes from the IBM emerging technology development and research teams, it provides introductory material to help developers get started with development of web services. The ETTK evolved from the Web Services Toolkit (WSTK) and includes the Axis library, a full implementation of the SOAP 1.1 specification for Java developers.

Axis makes it easy for Java developers to build SOAP-based web services from existing Java code. In its easiest form, a Java Archive Resource (JAR) file is dropped into the Axis webapps directory and Axis exposes the public methods as SOAP-based web services automatically. Consider the following Java class in Listing 1.


Listing 1. Simple Responder Java class
public class Responder
{
   public String Repeat( String theword )
   {
      return "You told me to say: " + theword;
   }
}

The Responder class has one public method named repeat. It takes a String value and returns a String value. By compiling the Responder class and packaging it into a JAR file you can offer the Responder as a web service by dropping the JAR file into the Axis webapps directory. Wasn't that very easy? Much more difficult is to expose a Java class with methods that expect to send or receive complex datatypes.

In Listing 2 is the Responder class having a second call that returns a Java Bean.


Listing 2. More complex Responder Java class
public class Responder
{
   public String repeat( String theword )
   {
      return "You told me to say: " + theword;
   }

   public MyID getMyID()
   {
      MyID theid = new MyID();
      return theid;
   }

   class MyID
   {
      private String name = "Frank Cohen";
      private int number = 10;
   
      public MyID();
   
      public String getName() { return name; }
      public void setName( String aname ) { name = aname; }
      public String getNumber() { return number; }
      public void setNumber( int num ) { number = num; }
   }
}

This Responder class includes an inner class that defines a JavaBean component. Unfortunately you can't just drop this compiled JAR into the Axis webapps directory and get access to the getMyID() method. Axis does not understand the complex datatype formatting of the MyID bean and will return a serialization exception.

The SOAP specification defines a set of simple datatypes -- String, Int, Long, and others -- and a means to provide support for complex datatypes. Most SOAP implementations come with an encoder and decoder for complex datatypes, including Java Bean components. This article shows how to use complex datatypes in Apache Axis and Apache SOAP.

As the maintainer of a popular open-source test framework and utility -- TestMaker -- I am in a unique position to see software development practices in action, especially with web services. Recently, I spent the better part of a day helping a developer at a large company use TestMaker to test a SOAP-based web service that emits a complex datatype. The developer needed help getting TestMaker to understand the custom response type. She also needed help creating the web service using Apache Axis on her host.

Here are the tasks she needed to accomplish:

  1. Create a web service using Apache Axis on the server that uses the built-in BeanSerializer to handle complex datatypes.
  2. Create a client to the web service using Apache SOAP's BeanSerializer class to handle complex datatypes.
  3. Run a performance test to learn the throughput of the serializers.

This article describes the steps needed to accomplish these tasks. All of the software mentioned in this article is available for free download (see Resources for a link).


Defining the web service

To begin, you will create a JavaBean representation of the complex datatype. This is shown in Listing 3.


Listing 3. JavaBean representation of complex datatype
package com.pushtotest;

/**
 * Forecast Java Bean for the weather Web Service
 */

public class Forecast {
    
    String zip = null;
    String city = null;
    String state = null;
    String date = null;
    String forecast = null;
    byte hi = 0;
    byte low = 0;
    byte precip = 0;
    
    /** Creates a new instance of WeatherBean */
    public Forecast() {
    }
    
    public void setZip( String thezip )
    {
        zip = thezip;
    }
    
    public String getZip()
    {
        return zip;
    }
    
    public void setCity( String thecity )
    {
        city = thecity;
    }
    
    public String getCity()
    {
        return city;
    }

    public void setState( String thestate )
    {
        state = thestate;
    }
    
    public String getState()
    {
        return state;
    }
    
    public void setDate( String thedate )
    {
        date = thedate;
    }

    public String getDate()
    {
        return date;
    }

    public void setForecast( String theforecast )
    {
        forecast = theforecast;
    }

    public String getForecast()
    {
        return forecast;
    }
    
    public void setLow( byte thelow )
    {
        low = thelow;
    }

    public byte getLow()
    {
        return low;
    }

    public void setHi( byte thehi )
    {
        hi = thehi;
    }
    
    public byte getHi()
    {
        return hi;
    }

    public void setPrecip( byte theprecip )
    {
        precip = theprecip;
    }

    public byte getPrecip()
    {
        return precip;
    }
}

Forecast is a straightforward Java class that encapsulates variables for weather reports, including a U.S. zip code, and temperatures. Forecast follows the JavaBean pattern of having a public initializer with no parameters and getter/setter methods for each of the encapsulated variables. As you will see, you will use the Forecast JavaBean component on both the server side and client side.

Next you define a weather web service. It receives a zip code value and returns a Forecast object. The interface to the weather web service is described in the the WSDL document shown in Listing 4.


Listing 4. WSDL for weather service
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
   targetNamespace="urn:weather"
   xmlns:impl="urn:weather"
   xmlns:intf="urn:weather"
   xmlns:apachesoap="http://xml.apache.org/xml-soap"
   xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
   xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns:tns2="http://weather"
   xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
   xmlns="http://schemas.xmlsoap.org/wsdl/">
 <wsdl:types>
  <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://weather">
   <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
   <complexType name="Forecast">
    <sequence>
     <element name="zip" nillable="true" type="xsd:string"/>
     <element name="city" nillable="true" type="xsd:string"/>
     <element name="state" nillable="true" type="xsd:string"/>
     <element name="date" nillable="true" type="xsd:string"/>
     <element name="forecast" nillable="true" type="xsd:string"/>
     <element name="hi" type="xsd:byte"/>
     <element name="low" type="xsd:byte"/>
     <element name="precip" type="xsd:byte"/>
    </sequence>
   </complexType>
  </schema>
 </wsdl:types>

   <wsdl:message name="getWeatherResponse">
      <wsdl:part name="getWeatherReturn" type="tns2:Forecast"/>
   </wsdl:message>

   <wsdl:message name="getWeatherRequest">
      <wsdl:part name="in0" type="xsd:string"/>
   </wsdl:message>

   <wsdl:portType name="Weather">
      <wsdl:operation name="getWeather" parameterOrder="in0">
         <wsdl:input name="getWeatherRequest" message="impl:getWeatherRequest"/>
         <wsdl:output name="getWeatherResponse" message="impl:getWeatherResponse"/>
      </wsdl:operation>
   </wsdl:portType>

   <wsdl:binding name="weatherSoapBinding" type="impl:Weather">
      <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
      <wsdl:operation name="getWeather">
         <wsdlsoap:operation soapAction=""/>
         <wsdl:input name="getWeatherRequest">
            <wsdlsoap:body
               use="encoded"
               encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
               namespace="urn:weather"/>
         </wsdl:input>
         <wsdl:output name="getWeatherResponse">
            <wsdlsoap:body
               use="encoded"
               encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
               namespace="urn:weather"/>
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>

   <wsdl:service name="WeatherService">
      <wsdl:port name="weather" binding="impl:weatherSoapBinding">
         <wsdlsoap:address 
         location="http://examples.pushtotest.com:92/ axis/servlet/AxisServlet"/>
      </wsdl:port>

   </wsdl:service>

</wsdl:definitions>

To build the server-side of the web service you define the weather Java class using the code shown in Listing 5.


Listing 5. Weather class
/*
 * weather.java
 */

package com.pushtotest;

public class weather {
    
    /** Creates a new instance of weather */
    public weather() {
    }
    
    public Forecast getWeather( String ziprq )
    {
        Forecast fb = new Forecast();

        fb.setZip( ziprq );
        fb.setCity( "Campbell" );
        fb.setState( "CA" );
        fb.setDate( "April 11, 2003" );
        fb.setForecast( "20 percent chance of rain." );
        
        return fb;
    }
}

The weather class defines a single getWeather method that receives a zip code value in a String object and returns a Forecast object. Since you will be using SOAP RPC encoding, the SOAP stack takes care of unmarshalling the request and then marshalling the Forecast object into a response.

A simple Ant build script compiles the weather and Forecast objects into class files and then into a weather.jar archive file. The Ant build script -- build.xml -- is found in the source files for the web service (see Resources for a link).

Once built, weather.jar is ready to be installed as a web service on an Apache Axis server. Apache Axis provides an easy installation mechanism through Web Service Deployment Descriptor (WSDD) formatted files. WSDD is an Axis defined XML format that defines the installation parameters for a web service. The WSDD for the weather web service is shown in Listing 6.


Listing 6. WSDD for weather service
<!-- This file deploys the weather Web Service onto an Apache Axis server ->

<deployment
    xmlns="http://xml.apache.org/axis/wsdd/"
    xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

  <!-- Services from Weather service -->

  <service name="weather" provider="java:RPC" style="rpc" use="encoded">
      <parameter name="wsdlTargetNamespace" value="urn:weather"/>
      <parameter name="wsdlServiceElement" value="WeatherService"/>
      <parameter name="wsdlServicePort" value="weather"/>
      <parameter name="className" value="weather.ws.WeatherSoapBindingImpl"/>
      <parameter name="wsdlPortType" value="Weather"/>
      <operation name="getWeather"
         qname="operNS:getWeather"
         xmlns:operNS="urn:weather"
         returnQName="getWeatherReturn"
         returnType="rtns:Forecast"
         xmlns:rtns="http://weather" >
      <parameter name="in0"
         type="tns:string"
         xmlns:tns="http://www.w3.org/2001/XMLSchema"/>
      </operation>
      <parameter name="allowedMethods" value="getWeather"/>
      <parameter name="scope" value="Session"/>

      <typeMapping
        xmlns:ns="http://weather"
        qname="ns:Forecast"
        type="java:com.pushtotest.Forecast"
        serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
        deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
        encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </service>
</deployment>

 <service name="forecast" provider="java:RPC">
  <parameter name="allowedMethods" value="*"/>
  <parameter name="className" value="com.pushtotest.forecast.Forecast"/>
  <beanMapping
     qname="myNS:Forecast"
     xmlns:myNS="urn:ForecastService"
     languageSpecificType="java:com.pushtotest.forecast.ForecastBean"/>

 </service>

There are two ways to install the web service using this WSDD file. With Axis running, use this at the command line of a shell:

java org.apache.axis.client.AdminClient deploy.wsdd

As an alternative, if Axis is not running use this at the command line of a shell:

java org.apache.axis.utils.Admin server deploy.wsdd

While trying to install the web service on Apache Axis 1.1 release candidate 2 (rc2) I found Axis throws exceptions when deploying the weather web service. Axis reports "class not found" problems with the installation. Checking the Axis users mailing list, I found that there are incompatibilities between Axis 1.1 rc2 and Apache Tomcat 4.0.3. At the time of this writing I have not heard from other Axis users for a workaround to the problem. So I offer my own workaround here. Add the following snippet of configuration codes (shown in Listing 7) to the Axis configuration file at servlet_container/webapps/axis/WEB-INF/server-config.wsdd.


Listing 7. Code snippet
<service name="weather" provider="java:RPC">
  <parameter name="allowedMethods" value="*"/>
  <parameter name="className" value="com.pushtotest.weather"/>
  <beanMapping
     qname="myNS:Forecast"
     xmlns:myNS="urn:ForecastService"
     languageSpecificType="java:com.pushtotest.Forecast"/>
</service>

This manually adds the weather web service to Axis and maps the Forecast object in the response to the Apache Axis BeanSerializer object. The BeanSerializer provides SOAP RPC encoding of any object that follows the JavaBean pattern (described earlier).

Depending on the method you use to install the weather web service, the Axis service should be restarted to make the web service available.

PushToTest provides the weather web service on its free http://examples.pushtotest.com service to help developers, QA technicians and IT managers understand the concepts behind testing web services for scalability, performance, and functionality. To view the services hosted there try browsing this URL http://examples.pushtotest.com:92/axis/servlet/AxisServlet. You should see that the weather service offers a single getWeather method.

So far, I have described the implementation details of the weather web service. You then were able to build the weather web service and deploy it on an Apache Axis server. Next comes the effort to make the client side.


The client side

Many SOAP libraries are available to build the client-side of the weather web service. This article presents TestMaker, a test framework and tool that natively supports SOAP-based web services. Plus, the TestMaker environment is designed to facilitate testing web services for scalability, performance, and functionality. See the Resources section below for details.

TestMaker is a framework and utility for building intelligent test agents. TestMaker comes with a library of protocol handlers called the Test Object Oriented Library (TOOL.) A TestMaker test agent script is written in Jython (the Python language implemented entirely in Java.) The Jython scripts instantiate TOOL protocol handler objects. When a SOAP protocol handler needs to make a request to a host it uses the included Apache SOAP stack to marshal and unmarshal the request and response.

The WSDL to this service notes that a client may access the service through this URL http://examples.pushtotest.com:92/axis/servlet/AxisServlet. Requests must contain a single String object holding a U.S. zip code. For the purpose of this article, the weather web service does not really check the weather, but instead returns the zip code in the Forecast object that is returned.

The entire TestMaker test agent script is shown in Listing 8, followed by a step-by-step explanation. The script is named SOAP_BeanSerializer.a and is found in the download archive reference below in the Resources section.


Listing 8. TestMaker script
# Import tells TestMaker where to find Tool objects
from com.pushtotest.tool.protocolhandler import ProtocolHandler, 
SOAPProtocol, SOAPBody, SOAPHeader
from com.pushtotest.tool.response import Response
from java.lang import Long, Integer, String
from com.pushtotest import Forecast

# These classes are provided by the Apache SOAP library
from org.apache.soap.encoding.soapenc import BeanSerializer
from org.apache.soap.util.xml import QName
from org.apache.soap import Constants

print "Agent started."

protocol = ProtocolHandler.getProtocol("soap")
body = SOAPBody()
protocol.setBody(body)

protocol.setHost("examples.pushtotest.com")
protocol.setPath("axis/servlet/AxisServlet")
protocol.setPort( 92 )

# Send a request to the Forecast.getForecast() method on the host
body.setTarget("weather")
body.setMethod("getWeather")

# The service accepts a zip code parameter. The service will response with
# a Java Bean containing the forecast (which is made-up for this example.)

body.addParameter( "ziprq", String, "95008", None )

# Tells the Apache SOAP library to use the BeanSerializer when it receives
# a response from the ForecastService.
beanSer = BeanSerializer()
qName = QName("urn:ForecastService", "Forecast")
protocol.setMapTypes( Constants.NS_URI_SOAP_ENC, qName, Forecast, beanSer, beanSer  )

response = protocol.connect()

print "Response from host:"
print response

print "Ended."

The TestMaker script begins by using the import command to identity objects in the TOOL library and Apache SOAP library that will be used later in the script:

# Import tells TestMaker where to find Tool objects
from com.pushtotest.tool.protocolhandler import ProtocolHandler, 
SOAPProtocol, SOAPBody, SOAPHeader
from com.pushtotest.tool.response import Response
from java.lang import Long, Integer, String
from com.pushtotest import Forecast

# These classes are provided by the Apache SOAP library
from org.apache.soap.encoding.soapenc import BeanSerializer
from org.apache.soap.util.xml import QName
from org.apache.soap import Constants

With the objects imported, the script instantiates protocol handler objects:

protocol = ProtocolHandler.getProtocol("soap")

The script instantiates a new SOAP protocol handler. This handler is referred to by the protocol variable:

body = SOAPBody()
protocol.setBody(body)

The script instantiates a new SOAPBody object to hold the zip code parameter that will be sent in the request to the weather web service.

The script identifies where to find the weather web service by identifying the host by using a URL, path, and port number:

protocol.setHost("examples.pushtotest.com")
protocol.setPath("axis/servlet/AxisServlet")
protocol.setPort( 92 )

The script identifies the getWeather method of the weather object on the host as the destination target for the request to the web service:

body.setTarget("weather")
body.setMethod("getWeather")

The service accepts a zip code parameter encoded in a simple String object:

body.addParameter( "ziprq", String, "95008", None )

The addparameter method provides a lot of flexibility. For example, if the weather web service received a Forecast object, instead of responding with one, you could use this command:

body.addParameter( "theForecast", Forecast, myForecast, None )

This would tell TOOL to encode the myForecast object, which is a Forecast object type, and send it to the host. In other words, any object (Jython or Java) may be marshalled through TOOL's addParameter method.

If you instructed the script to make the request to the weather web service without any extra configuration the TestMaker SOAP stack on the client side will throw an exception like that shown in Listing 9.


Listing 9. Exception
com.pushtotest.tool.ToolException: Error making SOAP RPC call: No Deserializer found to
deserialize a 'urn:ForecastService:Forecast'
using encoding style 'http://schemas.xmlsoap.org/soap/encoding/'.
    at com.pushtotest.tool.protocolhandler.SOAPProtocol.soapRpcCall(SOAPProtocol.java:297)
    at com.pushtotest.tool.protocolhandler.SOAPProtocol.connect(SOAPProtocol.java:254)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:324)
    at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java)
    at org.python.core.PyMethod.__call__(PyMethod.java)
    at org.python.core.PyObject.__call__(PyObject.java)
    at org.python.core.PyInstance.invoke(PyInstance.java)
    at org.python.pycode._pyx5.f$0(D:\agents\Serializers\SOAP_BeanSerializer.a:52)
    at org.python.pycode._pyx5.call_function(D:\agents\Serializers\SOAP_BeanSerializer.a)
    at org.python.core.PyTableCode.call(PyTableCode.java)
    at org.python.core.PyCode.call(PyCode.java)
    at org.python.core.Py.runCode(Py.java)
    at org.python.core.__builtin__.execfile_flags(__builtin__.java)
    at org.python.util.PythonInterpreter.execfile(PythonInterpreter.java)
    at com.pushtotest.testmaker_module.agentRunner$1$Job.run(Unknown Source)
    at org.netbeans.core.execution.RunClassThread.run(RunClassThread.java:119)
com.pushtotest.tool.ToolException: com.pushtotest.tool.ToolException: Error making 
SOAP RPC call: No Deserializer found to
deserialize a 'urn:ForecastService:Forecast'
using encoding style 'http://schemas.xmlsoap.org/soap/encoding/'.

The TestMaker SOAP stack on the client side does not know what to do with the Forecast object in the response from the weather web service. A serializer object maps an XML response into a Java object.

Fortunately the Apache SOAP library includes a BeanSerializer class just like Apache Axis on the server side did above. By adding a few lines of TestMaker script the Apache SOAP library in TestMaker will use the BeanSerializer class to unmarshal the Forecast object in the response.

Earlier, this agent script imported the Forecast object using:

from com.pushtotest import Forecast

This tells the class loader to look through the TestMaker classpath for the com.pushtotest.Forecast object. TestMaker maintains its own classpath to facilitate running the same test agents remotely in a companion product from PushToTest called TestNetwork. Details on TestNetwork are found below in the Resources section.

The Forecast object is compiled into the weather.jar script that was earlier loaded onto the Apache Axis host. Now TestMaker references the same weather.jar object on the client-side. To do so edit the testmaker_home/testmaker/bin/runide.cfg file and add:

-cp:a D:/agents/Serializers/dist/weather.jar

You will need to modify the path to match the configuration on your machine running TestMaker.

The next step in the SOAP_BeanSerializer.a script is to tell TestMaker how to handle the Forecast Java Bean in the response from the weather web service:

beanSer = BeanSerializer()
qName = QName("urn:ForecastService", "Forecast")
protocol.setMapTypes( Constants.NS_URI_SOAP_ENC, qName, Forecast, beanSer, beanSer  )

This tells the Apache SOAP library to use the BeanSerializer when it receives a Forecast complex object type response from the weather web service.

The connect method instructs the TOOL protocol handler to marshal the request and contact the weather web service host:

response = protocol.connect()

Upon completion the connect method returns a new response object:

print "Response from host:"
print response

See the documentation on TOOL for a complete list of methods provided in the response object. For the sake of brevity, this script simply prints the response object to display the contents of the Forecast JavaBean component.

A successful call to the weather web service host will look like Listing 10 in TestMaker's output window.


Listing 10. Successful call to weather service host
Agent running: SOAP_BeanSerializer.a
Description:
  SOAP-based Web Services may send and receive complex datatypes. This agent
  accesses a Web Service that returns a Java Bean containing several values.
  The script uses the Apache SOAP BeanSerializer to unmarshal the Java Bean
  encoded response from the examples.pushtotest.com host.
Agent started.
Response from host:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    >
 <SOAP-ENV:Body>
  <ns1:getWeatherResponse 
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
     xmlns:ns1="weather">
   <getWeatherReturn href="#id0"/>
  </ns1:getWeatherResponse>
  <multiRef id="id0" SOAP-ENC:root="0"
     encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
     xsi:type="ns3:Forecast" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
     xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/:encodingStyle"
     xmlns:ns3="urn:ForecastService">
   <date xsi:type="xsd:string">April 11, 2003</date>
   <zip xsi:type="xsd:string">95008</zip>
   <city xsi:type="xsd:string">Campbell</city>
   <state xsi:type="xsd:string">CA</state>
   <forecast xsi:type="xsd:string">20 percent chance of rain.</forecast>
   <low xsi:type="xsd:byte">0</low>
   <hi xsi:type="xsd:byte">0</hi>
   <precip xsi:type="xsd:byte">0</precip>
  </multiRef>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Ended.


Conclusion

This article presented the technique to use complex datatypes in a web service. On the server side, you used Apache Axis to create a web service that receives a simple data type and responds with a JavaBean component encoded in a complex datatype. On the client side, you used TestMaker -- that in-turn used Apache SOAP -- to send the request and receive the JavaBean component.



Download

NameSizeDownload method
ws-mapprobcode.zipHTTP

Information about download methods


Resources

About the author

Frank Cohen is the "go to" guy when enterprises need to test and solve problems in complex interoperating information systems, especially Web services. Frank is Founder of PushToTest, a test automation solutions business and author of several books on testing information systems. For the past 20 years he led some of the software industry's most successful products, including Norton Utilities for the Macintosh, Stacker, and SoftWindows. He began by writing operating systems for microcomputers, helping establish video games as an industry, helping establish the Norton Utilities franchise, leading Apple's efforts into middleware and Internet technologies, and most recently serving as principal architect for the Sun Community Server, Inclusion.net (OTC: IINC), and TuneUp.com. He serves as an active member and past board member of the Software Developers Forum, the leading computer software industry association in the Silicon Valley of California. You can reach Frank at fcohen at pushtotest.com.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=SOA and web services
ArticleID=11806
ArticleTitle=Complex datatypes in SOAP-based web services
publish-date=05262003
author1-email=
author1-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Try IBM PureSystems. No charge.

Special offers