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

advertisement

AddThis Social Bookmark Button

Java and XML: SOAP
Pages: 1, 2, 3, 4, 5, 6, 7

Getting Dirty

There are three basic steps in writing any SOAP-based system, and I'll look at each in turn:

  • Decide on SOAP-RPC or SOAP messaging
  • Write or obtain access to a SOAP service
  • Write or obtain access to a SOAP client

The first step is to decide if you want to use SOAP for RPC-style calls, in which a remote procedure is invoked on a server, or for messaging, in which a client simply sends pieces of information to a server. I'll detail these processes in the next section. Once you've made that design decision, you'll need to access, or code up, a service. Of course, since we're all Java pros here, this chapter shows you how to code up your own. Finally, you'll need to write the client for this service, and watch things take off.

RPC or Messaging?

Your first task is actually not code-related but design-related. You need to determine if you want an RPC service or a messaging one. The first, RPC, is something you should be pretty familiar with after the last chapter. A client invokes a remote procedure on a server somewhere, and then gets some sort of response. In this scenario, SOAP is simply acting as a more extensible XML-RPC system, allowing better error handling and passing of complex types across the network. This is a concept you should already understand, and because it turns out that RPC systems are simple to write in SOAP, I'll start off there. This chapter describes how to write an RPC service, and then an RPC client, and put the system in action.

The second style of SOAP processing is message-based. Instead of invoking remote procedures, it provides for transfer of information. As you can imagine, this is pretty powerful, and doesn't depend on a client knowing about a particular method on some server. It also models distributed systems more closely, allowing packets of data (packet in the figurative sense, not in the network sense) to be passed around, keeping various systems aware of what other systems are doing. It is also more complicated than the simpler RPC-style programming, so I'll cover it in the next chapter with other business-to-business details, after you're well grounded in SOAP-RPC programming.

The actual process of making this decision is left up to you, like most design issues. Look at your application and determine exactly what you want SOAP to do for you. If you have a server and a set of clients that just need to perform tasks remotely, then RPC is probably going to be well-suited for your needs. However, in larger systems that are exchanging data rather than performing specific business functions on request, SOAP's messaging capabilities may be a better match.

An RPC Service

With the formalities out of the way, it's time to get going, fast and furious. As you'll recall from the last chapter, in RPC you need a class that is going to have its methods invoked remotely.

Code artifacts

I'll start by showing you some code artifacts to have available on the server. These artifacts are classes with methods that are exposed to RPC clients.

You can also use scripts through the Bean Scripting Framework, but for the sake of space I won't cover that here. Check out the upcoming O'Reilly SOAP book, as well as the online documentation at http://xml.apache.org/soap, for more details on script support in SOAP.

Rather than use the simple class from last chapter, I offer a slightly more complex example to show you what SOAP can do. In that vein, Example 12-4 is a class that stores a CD inventory, such as an amazon.com style application might use. I'm introducing a basic version here, and will add to that later in the chapter as well.

Example 12-4: The CDCatalog class

package javaxml2;
 
import java.util.Hashtable;
 
public class CDCatalog {
 
  /** The CDs, by title */
  private Hashtable catalog;
 
  public CDCatalog( ) {
    catalog = new Hashtable( );
 
    // Seed the catalog
    catalog.put("Nickel Creek", "Nickel Creek");
    catalog.put("Let it Fall", "Sean Watkins");
    catalog.put("Aerial Boundaries", "Michael Hedges");
    catalog.put("Taproot", "Michael Hedges");
  }
 
  public void addCD(String title, String artist) {
    if ((title == null) || (artist == null)) {
      throw new IllegalArgumentException("Title and artist cannot be null.");
    }
    catalog.put(title, artist);    
  }
 
  public String getArtist(String title) {
    if (title == null) {
      throw new IllegalArgumentException("Title cannot be null.");
    }
 
    // Return the requested CD
    return (String)catalog.get(title);
  }
 
  public Hashtable list( ) {
    return catalog;
  }
}

This allows adding a new CD, searching for an artist by a CD title, and getting all current CDs. Take note that the list( ) method returns a Hashtable, and there is nothing special I have to do to make that work; Apache SOAP provides automatic mapping of the Hashtable Java type, much as XML-RPC did.

Compile this class, and make sure you've got everything typed in (or downloaded, if you choose) correctly. Notice that the CDCatalog class has no knowledge about SOAP. This means you can take your existing Java classes and expose them through SOAP-RPC, which reduces the work required on your end to move to a SOAP-based architecture if needed.

Deployment descriptors

With the Java coding done, you now need to define a deployment descriptor. This specifies several key things to a SOAP server:

  • The URN of the SOAP service for clients to access
  • The method or methods available to clients
  • The serialization and deserialization handlers for any custom classes

The first is similar to a URL, and required for a client to connect to any SOAP server. The second is exactly what you expect: a list of methods letting the client know what are allowable artifacts for a SOAP client. It also lets the SOAP server, which I'll cover in a moment, know what requests to accept. And the third is a means of letting the SOAP server know how to handle any custom parameters; I'll come back to this in the next section when I add some more complex behavior to the catalog.

I'll show you the deployment descriptor and detail each item within it. Example 12-5 is the deployment descriptor for the CDCatalog service we're creating.

Example 12-5: The CDCatalog deployment descriptor

<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment"
       id="urn:cd-catalog"
>
 <isd:provider type="java"
        scope="Application"
        methods="addCD getArtist list"
 >
  <isd:java class="javaxml2.CDCatalog" static="false" />
 </isd:provider>
 
 <isd:faultListener>org.apache.soap.server.DOMFaultListener</isd:faultListener>
</isd:service>

First, I referenced the Apache SOAP deployment namespace, and then supplied a URN for my service through the id attribute. This should be something unique across services, and descriptive of the service. I showed about as much originality in naming the service as Dave Matthews did with his band, but it gets the job done. Then, I specified through the java element the class to expose, including its package name (through the class attribute), and indicated that the methods being exposed were not static ones (through the static attribute).

Next, I've specified a fault listener implementation to use. Apache's SOAP implementation provides two; I've used the first, DOMFaultListener. This listener returns any exception and fault information through an additional DOM element in the response to the client. I'll get back to this when I look at writing clients, so don't worry too much about it right now. The other fault listener implementation is org.apache.soap.server.ExceptionFaultListener. This listener exposes any faults through an additional parameter returned to the client. Since quite a few SOAP-based applications are already going to be working in Java and XML APIs like DOM, it's common to use the DOMFaultListener in most cases.

Pages: 1, 2, 3, 4, 5, 6, 7

Next Pagearrow