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

advertisement

AddThis Social Bookmark Button

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

In order to make this new method available in Apache SOAP, we'll need to redeploy the service using a modified deployment descriptor. We need to add getHighLow to the list of methods, and add an entry in the mappings section for the high/low object. The second mapping entry defines the HighLowa custom type, namespace-qualified using the service name urn:BasicTradingService. Here is the modified deployment descriptor:



<isd:service 
    xmlns:isd="http://xml.apache.org/xml-soap/deployment"
    id="urn:BasicTradingService">
  <isd:provider 
     type="java"
     scope="Application"
     methods="getTotalVolume getMostActive executeTrade executeStockTrade
              getHighLow">
    <isd:java 
       class="javasoap.book.ch5.BasicTradingService" 
       static="false"/>
  </isd:provider>
  
  <isd:faultListener>org.apache.soap.server.DOMFaultListener
  </isd:faultListener>
  <isd:mappings>
    <isd:map  
       encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
       xmlns:x="urn:BasicTradingService" qname="x:StockTrade"
       javaType="javasoap.book.ch5.StockTradeServer"
       java2XMLClassName="org.apache.soap.encoding.soapenc.BeanSerializer"
       xml2JavaClassName="org.apache.soap.encoding.soapenc.BeanSerializer"/>
    <isd:map  
       encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
       xmlns:x="urn:BasicTradingService" qname="x:HighLow"
       javaType="javasoap.book.ch5.HighLow_ServerSide"
       java2XMLClassName="org.apache.soap.encoding.soapenc.BeanSerializer"
       xml2JavaClassName="org.apache.soap.encoding.soapenc.BeanSerializer"/>
  </isd:mappings>    
</isd:service>

Now we can create a client application that invokes the getHighLow service method and receives a high/low object in return. For the Apache SOAP client, we'll use the HighLow_ClientSide class to represent the return value. Here's the new application:

package javasoap.book.ch5;
import java.net.*;
import java.util.*;
import org.apache.soap.*;
import org.apache.soap.rpc.*;
import org.apache.soap.encoding.*;
import org.apache.soap.encoding.soapenc.*;
import org.apache.soap.util.xml.*;
public class HighLowClient
{
  public static void main(String[] args) throws Exception 
  {
    URL url = new  
       URL("http://georgetown:8080/soap/servlet/rpcrouter");
    Call call = new Call(  );
    SOAPMappingRegistry smr = new SOAPMappingRegistry(  );
    call.setTargetObjectURI("urn:BasicTradingService");
    call.setMethodName("getHighLow");
    call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
    call.setSOAPMappingRegistry(smr);
    BeanSerializer beanSer = new BeanSerializer(  );
    // Map the High/Low type
    smr.mapTypes(Constants.NS_URI_SOAP_ENC,
             new QName("urn:BasicTradingService", "HighLow"),
             HighLow_ClientSide.class, beanSer, beanSer);
    String stock = "XYZ";
    Vector params = new Vector(  );
    params.addElement(new Parameter("stock", 
                           String.class, stock, null));
    call.setParams(params);
    Response resp;
    try {
      resp = call.invoke(url, "");
      Parameter ret = resp.getReturnValue(  );
      HighLow_ClientSide hilo = 
             (HighLow_ClientSide)ret.getValue(  );
      System.out.println(hilo);
    }
    catch (SOAPException e) {
      System.err.println("Caught SOAPException (" +
                         e.getFaultCode(  ) + "): " +
                         e.getMessage(  ));
    }
  }
}

smr.MapTypes( ) maps the HighLow custom type to the HighLow_ClientSide Java class. Just as before, we can use Apache's BeanSerializer to convert between XML and Java, since our class conforms to the JavaBeans property accessor pattern. We set up a single String parameter called stock to pass to the getHighLow method (although we don't actually make use of it in the server code). After the method is invoked, we cast the return value of resp.getReturnValue( ) to an instance of HighLow_ClientSide. Then we pass the return parameter variable, ret, to the System.out.println( ) method for display. This is all we need, since we implemented the toString( ) method in our HighLow_ClientSide class. When you run this example, you'll get the following output:

High: 110.375 Low: 109.5

Here's the SOAP envelope returned from this method invocation. The return element is typed as a HighLow that is namespace-qualified by the urnBasicTradingService namespace. The properties, which are child elements of the return element, are typed as floats and appear along with their corresponding values.

<SOAP-ENV:Envelope 
   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <SOAP-ENV:Body>
    <ns1:getHighLowResponse 
      xmlns:ns1="urn:BasicTradingService" 
      SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <return xsi:type="ns1:HighLow">
         <low xsi:type="xsd:float">109.5</low>
         <high xsi:type="xsd:float">110.375</high>
      </return>
   </ns1:getHighLowResponse>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

To return a HighLow using GLUE, we'll take the same steps we did for passing custom types. Again we'll separate our client-side work into another package, javasoap.book.ch5.client. Just restart the application of BasicTradingApp to get the service deployed. Now run the wsdl2java utility from the directory corresponding to the javasoap.book.ch5.client package:

wsdl2java http://georgetown:8004/glue/urn:BasicTradingService.wsdl 
    -p javasoap.book.ch5.client

Pages: 1, 2, 3

Next Pagearrow