A Simple SOAP Client

Talking to a SOAP server that provides Fibonacci numbers is not significantly harder than talking to an XML-RPC server. You just have to adjust the syntax of your request to use SOAP instead of XML-RPC. Again, we’ll talk to a Fibonacci generator I’ll develop in later chapters, but that can be previewed at http://www.elharo.com/fibonacci/SOAP. The body of each request document contains a calculateFibonacci element in the http://namespaces.cafeconleche.org/xmljava/ch3/ namespace. This element contains a single positive integer:

<?xml version="1.0"?>
<SOAP-ENV:Envelope
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
  <SOAP-ENV:Body>
    <calculateFibonacci 
      xmlns="http://namespaces.cafeconleche.org/xmljava/ch3/"
      type="xsi:positiveInteger">10</calculateFibonacci>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The server responds with a list of Fibonacci numbers using the vocabulary designed earlier in this chapter, enclosed in the usual SOAP response envelope. For example, here’s the response to a request for the first ten Fibonacci numbers:

<?xml version="1.0"?>
<SOAP-ENV:Envelope
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" />
  <SOAP-ENV:Body>
    <Fibonacci_Numbers 
      xmlns="http://namespaces.cafeconleche.org/xmljava/ch3/">
      <fibonacci index="1">1</fibonacci>
      <fibonacci index="2">1</fibonacci>
      <fibonacci index="3">2</fibonacci>
      <fibonacci index="4">3</fibonacci>
      <fibonacci index="5">5</fibonacci>
      <fibonacci index="6">8</fibonacci>
      <fibonacci index="7">13</fibonacci>
      <fibonacci index="8">21</fibonacci>
      <fibonacci index="9">34</fibonacci>
      <fibonacci index="10">55</fibonacci>
    </Fibonacci_Numbers>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Conceptually, the SOAP client is almost identical to Example 3.10. It reads one or more integers from the command lines, opens a URLConnection to the server, and POSTs each integer to the server wrapped inside a bunch of XML markup. It then receives a batch of XML markup in response which it prints on System.out. The markup used has changed. However, all the markup is just strings. One string is more or less the same as the next as far as Java is concerned. Example 3.11 shows the completed code.

Example 3.11. Connecting to a SOAP server with URLConnection

import java.net.*;
import java.io.*;


public class FibonacciSOAPClient {

  public final static String DEFAULT_SERVER 
   = "http://www.elharo.com/fibonacci/SOAP";
  public final static String SOAP_ACTION 
   = "http://www.example.com/fibonacci";

  public static void main(String[] args) {
  
    if (args.length == 0) {
      System.out.println(
       "Usage: java FibonacciSOAPClient index URL");
      return;
    }
    String input = args[0];
    String server = DEFAULT_SERVER;
    if (args.length >= 2) server = args[1];
    
    try {
      URL u = new URL(server);
      URLConnection uc = u.openConnection();
      HttpURLConnection connection = (HttpURLConnection) uc;
      
      connection.setDoOutput(true);
      connection.setDoInput(true);
      connection.setRequestMethod("POST");
      connection.setRequestProperty("SOAPAction", SOAP_ACTION);
      
      OutputStream out = connection.getOutputStream();
      Writer wout = new OutputStreamWriter(out);
      
      wout.write("<?xml version='1.0'?>\r\n");  
      wout.write("<SOAP-ENV:Envelope ");
      wout.write("xmlns:SOAP-ENV=");
      wout.write(
        "'http://schemas.xmlsoap.org/soap/envelope/' "
      );
      wout.write("xmlns:xsi=");
      wout.write(
        "'http://www.w3.org/2001/XMLSchema-instance'>\r\n"); 
      wout.write("  <SOAP-ENV:Body>\r\n");
      wout.write("    <calculateFibonacci ");
      wout.write(
    "xmlns='http://namespaces.cafeconleche.org/xmljava/ch3/'\r\n"
      ); 
      wout.write("    type='xsi:positiveInteger'>" + input 
       + "</calculateFibonacci>\r\n"); 
      wout.write("  </SOAP-ENV:Body>\r\n"); 
      wout.write("</SOAP-ENV:Envelope>\r\n"); 
      
      wout.flush();
      wout.close();
      
      InputStream in = connection.getInputStream();
      int c;
      while ((c = in.read()) != -1) System.out.write(c);
      in.close();

    }
    catch (IOException e) {
      System.err.println(e); 
    }
  
  } // end main

} // end FibonacciSOAPClient

The one new piece here is that SOAP 1.1 requires the client to set a SOAPAction field in the HTTP header. This is done with URLConnection’s setRequestProperty() method. Some servers may dispatch the request based on this field without actually parsing the body of the request. This server doesn't pay any attention to the SOAPAction field, however, so I just set it to a reaosnable default value. SOAP 1.2 will make SOAPAction optional.


Copyright 2001, 2002 Elliotte Rusty Haroldelharo@metalab.unc.eduLast Modified May 24, 2002
Up To Cafe con Leche