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


AddThis Social Bookmark Button O'Reilly Book Excerpts: Java and SOAP

Working with Complex Data Types, Part 3

Related Reading

Java and SOAP
By Robert Englander

by Robert Englander

Editor's Note: This is the third in a series of excerpts from "Chapter 5: Working with Complex Data Types" of Java and SOAP. This excerpt covers passing custom types as parameters.

Passing Custom Types as Parameters

As Java programmers, we certainly don't restrict ourselves to the classes found in the standard Java packages. A substantial part of our code exists as custom types, Java classes of our own creation that embody the functionality and characteristics of the systems we're building.

Consider the design of a Java class that contains all of the data necessary to specify a stock trade. This new class might contain the symbol for the stock being traded, the number of shares to trade, and an indication of the order type (buy or sell). When designing such a class, it's important to view it in the context of the larger system. That kind of analysis yields clues that can lead to decisions regarding the properties and behaviors to be given to the class. We all do this kind of work all the time; it's called software design. The result is a Java class that contains methods for accessing properties and behavior. Since SOAP is a data transport, we're interested in the properties of the class. That's what we want to transmit over the wire.

One common way to express the properties of a Java class is to use the JavaBeans design patterns. These patterns specify a naming convention to be used for the class's access methods. You may not be familiar with JavaBeans, but I bet you've seen this pattern many times. Here's how the property accessor pattern is described in the O'Reilly book Developing Java Beans:

The methods used for getting and setting property values should conform to the standard design pattern for properties. These methods are allowed to throw checked exceptions if desired, but this is optional. The method signatures are as follows:

public void set<PropertyName>(<PropertyType> value);
public <PropertyType> get<PropertyName>(  );
The existence of a matching pair of methods that conform to this pattern represents a read/write property with the name <PropertyName> of the type <PropertyType>. If only the get method exists, the property is considered to be read only, and if only the set method exists the property is considered to be write only. In the case where the <PropertyType> is boolean, the get method can be replaced or augmented with a method that uses the following signature:

public boolean is<PropertyName>(  );

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.

If you follow this pattern for naming property accessors, the accessor methods can be determined at runtime by using the Java reflection mechanism.[3] This is a convenient way for SOAP implementations to access the data values of a Java class instance in order to serialize the data in a SOAP message. It turns out that both Apache SOAP and GLUE take advantage of reflection. This means that all you need to do is follow a well-established naming convention, and you'll be well on your way to using custom classes in SOAP. Of course, there's a little more to it than that, so let's dig in.

First let's define a stock trade in terms of data that we want it to contain. It needs to have a stock symbol to represent the stock being traded; the symbol should be a string type element. It needs a boolean indicator that specifies whether the order is buy or sell. Lastly, it needs an integer that contains the number of shares to be traded. (In a real-world application, it might also contain various security credentials, the names of the purchaser and the broker, and many other things. Alternatively, this ancillary data could be represented in other objects.) Here's what an XML schema snippet for the stock trade might look like:

<element name="StockTrade" type="StockTrade"/>
<complexType name="StockTrade">
    <element name="symbol" type="xsd:string"/>
    <element name="buy" type="xsd:boolean"/>
    <element name="numshares" type="xsd:int"/>

Let's create a custom Java class for specifying a stock trade called StockTrade_ClientSide. Normally I'd name this class StockTrade, but I want to make it clear that I'll be using this class on the client side of the example. We'll be writing a similar class to be used on the server side that will have a corresponding name. I'm doing this to point out that you are not required to use the same Java class on both sides of the message transaction. In fact, it probably won't make sense to use the same class, and it often won't even be possible.

StockTrade_ClientSide has three read/write properties named Symbol, Buy, and NumShares that represent the stock symbol, the buy/sell indicator, and the number of shares to trade, respectively.

package javasoap.book.ch5;
public class StockTrade_ClientSide {
   String   _symbol;
   boolean  _buy;
   int      _numShares;
   public StockTrade_ClientSide(  ) {
   public StockTrade_ClientSide(String symbol, 
                      boolean buy, int numShares) {
      _symbol = symbol;
      _buy = buy;
      _numShares = numShares;
   public String getSymbol(  ) {
      return _symbol;
   public void setSymbol(String symbol) {
      _symbol = symbol;
   public boolean isBuy(  ) {
      return _buy;
   public void setBuy(boolean buy) {
      _buy = buy;
   public int getNumShares(  ) {
      return _numShares;
   public void setNumShares(int numShares) {
      _numShares = numShares;

Pages: 1, 2, 3, 4, 5

Next Pagearrow