ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Working with Complex Data Types, Part 3
Pages: 1, 2, 3, 4, 5

The only differences between this interface definition and the one we wrote ourselves are a different package declaration, the naming of the method parameters, and the executeStockTrade taking a parameter of StockTrade_ServerSide instead of StockTrade_ClientSide. Remember that the earlier version of IBasicTradingService won't work for us because GLUE defaults to using the same class on both client and server. At first glance, the use of the StockTrade_ServerSide class here seems to violate our desire to completely decouple the server code from the client code. But remember that the package declaration is javasoap.book.ch5.client, so this Java interface is not referencing the same StockTrade_ServerSide class being used by our server, which belongs to a different package. Let's take a look at the StockTrade_ServerSide class generated by wsdl2java and placed in the file named StockTrade_ServerSide.java:

// generated by GLUE
package javasoap.book.ch5.client;
public class StockTrade_ServerSide
  {
  public int _shares;
  public boolean _buyOrder;
  public String _stock;
  }

This is only a shadow of the corresponding class in the javasoap.book.ch5 package that the server side uses. It does, however, properly reflect the data values. We'll be creating an instance of this class in our client application to pass to the service, as this is the type expected by the executeStockTrade( ) method of the IBasicTradingService interface that was generated.

The third file generated by wsdl2java is BasicTradingService.map, which contains the mapping schema mentioned earlier. You can take a look at the contents of the mapping file on your own; suffice it to say that it contains XML entries that define field mappings between the client-side and server-side Java. The last generated file is BasicTradingServiceHelper.java, which contains a helper class for performing the bind( ) operation. I don't use that helper class, so we'll ignore it here.

It's taken far longer to describe the process than it takes to perform it. Now let's move on to writing the client application:

package javasoap.book.ch5.client;
import electric.registry.RegistryException;
import electric.registry.Registry;
import electric.xml.io.Mappings;
public class StockTradeClient2 {
   public static void main(String[] args) throws Exception 
   {
      try {
        Mappings.readMappings("BasicTradingService.map");
        IBasicTradingService srv = 
          (IBasicTradingService)Registry.bind(
          "http://georgetown:8004/glue/urn:BasicTradingService.wsdl",
          IBasicTradingService.class);
        StockTrade_ServerSide trade =   
                       new StockTrade_ServerSide(  );
        trade._stock = "MINDSTRM";
        trade._buyOrder = true;
        trade._shares = 500;
        String desc = srv.executeStockTrade(trade);
        System.out.println("Trade Description is: " + desc);
    }
    catch (RegistryException e)
    {
       System.out.println(e);
    }
  }
}

In This Series

Working with Complex Data Types, Part 4
This is the last in a series of book excerpts on working with complex data types from Java and SOAP. In this excerpt, learn about returning custom types, using a stock market example.

Working with Complex Data Types, Part 2
In part two in this series of book excerpts from Java and SOAP, learn about returning arrays.

Working with Complex Data Types, Part 1
In this excerpt on complex data types from Java and SOAP, the authors discuss passing arrays as parameters.

The critical step is to read the mappings before you perform the bind operation. This is done by calling the readMappings( ) method of the electric.xml.io.Mappings class provided as part of GLUE. After the bind( ) call, we simply create an instance of StockTrade_ServerSide, set its field values, and call the executeStockTrade method. The output from running this application should be:

Trade Description is: Buy 500 of MINDSTRM

Now let's look at the SOAP envelope generated by this application. As we've come to expect, the executeStockTrade element is namespace-qualified using the name of the service. The child element arg0 is a reference to a separately serialized element named id0, just as GLUE generated for an array parameter. This example shows us why GLUE has been generating the ns2 namespace identifier that seems to reference the package where the implementing server-side class resides. Here that namespace is used to qualify the value of the xsi:type attribute, with a value corresponding to the name of the implementing class StockTrade_ServerSide. The child elements of the id0 element contain the data fields for the custom type.

<soap:Envelope 
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' 
  xmlns:xsd='http://www.w3.org/2001/XMLSchema' 
  xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'
  xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/' 
  soap:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
    <soap:Body>
      <n:executeStockTrade xmlns:n='urn:BasicTradingService'>
        <arg0 href='#id0'/>
      </n:executeStockTrade>
      <id0 id='id0' soapenc:root='0' 
       xmlns:ns2=
       	 'http://www.themindelectric.com/package/javasoap.book.ch5/'
       xsi:type='ns2:StockTrade_ServerSide'>
        <_shares xsi:type='xsd:int'>500</_shares>
        <_buyOrder xsi:type='xsd:boolean'>true</_buyOrder>
        <_stock xsi:type='xsd:string'>MINDSTRM</_stock>
      </id0>
    </soap:Body>
</soap:Envelope>

In the next and final installment, learn about returning custom types.

Robert Englander is Principal Engineer and President of MindStream Software, Inc. (www.mindstrm.com). He provides consulting services in software architecture, design, and development, as well as developing frameworks for use on client projects.

Java and SOAP

Related Reading

Java and SOAP
By Robert Englander