September 30, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

WSDL Essentials

  • February 25, 2003
  • By Developer.com Staff
  • Send Email »
  • More Articles »

Complex Types

Our final topic is the use of complex data types. For example, consider a home monitoring service that provides a concise update on your home. The data returned could include multiple data elements, such as the current temperature, security status, and whether the garage door is open or closed. Encoding this data into WSDL requires additional knowledge of XML Schemas, which reinforces the main precept that the more you know about XML Schemas, the better you will understand complex WSDL files.

To explore complex types, consider the WSDL file in Example 6-10. This WSDL file describes our Product Service from Chapter 5. The complex types are indicated in bold.

Example 6-10: ProductService.wsdl

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="ProductService"
  targetNamespace="http://www.ecerami.com/wsdl/ProductService.wsdl"
  xmlns="http://schemas.xmlsoap.org/wsdl/"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:tns="http://www.ecerami.com/wsdl/ProductService.wsdl"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsd1="http://www.ecerami.com/schema">
 
   <types>
     <xsd:schema
         targetNamespace="http://www.ecerami.com/schema"
         xmlns="http://www.w3.org/2001/XMLSchema">
         <xsd:complexType name="product">
            <xsd:sequence>
               <xsd:element name="name" type="xsd:string"/>
               <xsd:element name="description" type="xsd:string"/>
               <xsd:element name="price" type="xsd:double"/>
               <xsd:element name="SKU" type="xsd:string"/>
            </xsd:sequence>
         </xsd:complexType>
      </xsd:schema>
   </types>
 
   <message name="getProductRequest">
     <part name="sku" type="xsd:string"/>
   </message>
   
   <message name="getProductResponse">
     <part name="product" type="xsd1:product"/>
   </message>
 
   <portType name="Product_PortType">
     <operation name="getProduct">
       <input message="tns:getProductRequest"/>
       <output message="tns:getProductResponse"/>
     </operation>
   </portType>
 
   <binding name="Product_Binding" type="tns:Product_PortType">
     <soap:binding style="rpc"
         transport="http://schemas.xmlsoap.org/soap/http"/>
     <operation name="getProduct">
       <soap:operation soapAction="urn:examples:productservice"/>
       <input>
         <soap:body
             encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
             namespace="urn:examples:productservice"
             use="encoded"/>
       </input>
       <output>
         <soap:body
             encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
             namespace="urn:examples:productservice" use="encoded"/>
       </output>
     </operation>
   </binding>
 
   <service name="Product_Service">
     <port name="Product_Port" binding="tns:Product_Binding">
       <soap:address location="http://localhost:8080/soap/servlet/rpcrouter"/>
     </port>
   </service>
</definitions>

The service in Example 6-10 describes a getProduct operation that returns a complex product type for encapsulating product information, including product name, description, price, and SKU number.

The new product type is defined in much the same manner as the array definition from the previous example. The main difference is that we are now using the sequence element. The sequence element specifies a list of subelements and requires that these elements appear in the order specified. XML Schemas also enable you to specify cardinality via the minOccurs and maxOccurs attributes. If these attributes are absent (as in our example), they default to 1, requiring that each subelement must occur exactly one time.

Each subelement can also have its own data type, and you can see that we have mixed and matched string data types with double data types in our example.

Automatically invoking complex type services

To automatically invoke the Product Service, we return to the GLUE wsdl2java tool. This time around, GLUE will generate a Java interface class and a Java helper class, along with two additional files for handling the new complex type.

For example, the following command:

wsdl2java.bat http://localhost:8080/wsdl/ProductService.wsdl -p com.ecerami.
    wsdl.glue

generates the following output:

write file IProduct_Service.java
write file Product_ServiceHelper.java
write file product.java
write file Product_Service.map

The first two files in the output listing are familiar. The first file is a Java interface mirroring the service; the second file is a helper class for dynamically binding to the specified service. (See Example 6-11 and Example 6-12.)

Example 6-11: IProduct_Service.java

// generated by GLUE
 
package com.ecerami.wsdl.glue;
 
public interface IProduct_Service
  {
  product getProduct( String sku );
  }

Example 6-12: Product_ServiceHelper.java

// generated by GLUE
 
package com.ecerami.wsdl.glue;
 
import electric.registry.Registry;
import electric.registry.RegistryException;
 
public class Product_ServiceHelper
  {
  public static IProduct_Service bind(  ) throws RegistryException
    {
    return bind( "http://localhost:8080/wsdl/ProductService.wsdl" );
    }
 
  public static IProduct_Service bind( String url ) 
   throws RegistryException
    {
    return (IProduct_Service)
      Registry.bind( url, IProduct_Service.class );
    }
  }

The third file in the output listing, product.java, represents a simple container class for encapsulating product data. (See Example 6-13.) GLUE essentially takes all the complex types defined within the WSDL file and creates a container class for each type. Each subelement is then transformed into a public variable for easy access. For example, the product class has four public variables, name, description, price, and SKU, corresponding to our new complex data type. Note also that the public variables match the XML Schema types specified within the WSDL file; for example, name is declared as a String, whereas price is declared as a double.

Example 6-13: product.java

// generated by GLUE
 
package com.ecerami.wsdl.glue;
 
public class product
  {
  public java.lang.String name;
 
  public java.lang.String description;
 
  public double price;
 
  public java.lang.String SKU;
  }  

Finally, GLUE generates a Java-to-XML Schema mapping file. (See Example 6-14.) The file itself is extremely concise and is responsible for converting Java to XML Schema types and vice versa. (See Figure 6-13.) The root complexType element indicates that elements of type product should be transformed into the product class located in com.ecerami.wsdl.glue. Inside the root complex type, there is a one-to-one mapping between the XML Schema type and the public Java variable. For example, the element name is mapped to the product.name variable, and the type is specified as string. Likewise, the element price is mapped to the product.price variable, and the type is specified as double.

Figure 6-13. The GLUE Java-to-XML Schema mapping file

 

Example 6-14: Product_Service.map

<?xml version='1.0' encoding='UTF-8'?>
<!--generated by GLUE-->
<mappings xmlns='http://www.themindelectric.com/schema/'>
 <schema
  xmlns='http://www.w3.org/2001/XMLSchema'
  targetNamespace='http://www.ecerami.com/schema'
  xmlns:electric='http://www.themindelectric.com/schema/'>
  <complexType name='product' electric:class='com.ecerami.wsdl.glue.product'>
   <sequence>
    <element name='name' electric:field='name' type='string'/>
    <element name='description'
       electric:field='description' type='string'/>
    <element name='price' electric:field='price' type='double'/>
    <element name='SKU' electric:field='SKU' type='string'/>
    </sequence>
  </complexType>
 </schema>
</mappings>

To invoke the Product Service, you must first explicitly load the mapping file via the GLUE Mappings class:

Mappings.readMappings("Product_Service.map");

You can then access the service just like in the previous example. See Example 6-15 for the complete invocation program. Here is some sample output:

Product Service
Name:  Red Hat Linux
Description:  Red Hat Linux Operating System
Price:  54.99

Example 6-15: Invoke_Product.java

package com.ecerami.wsdl;
 
import java.io.IOException;
import electric.xml.io.Mappings;
import electric.xml.ParseException;
import electric.registry.RegistryException;
import com.ecerami.wsdl.glue.*;
 
/**
 * SOAP Invoker.  Uses the Product_ServiceHelper to invoke the Product
 * SOAP service.  All other .java files are automatically generated 
 * by GLUE.
*/
public class Invoke_Product {
 
  /**
   * Get Product via SOAP Service
   */
  public product getProduct (String sku) throws Exception {
    //  Load Java <--> XML Mapping
    Mappings.readMappings("Product_Service.map");
    //  Invoke Service
    IProduct_Service service = Product_ServiceHelper.bind(  );
    product prod = service.getProduct(sku);
    return prod;
  }
 
  /**
   * Main Method
   */
  public static void main (String[] args) throws Exception {
    Invoke_Product invoker = new Invoke_Product(  );
    System.out.println ("Product Service");
    product prod = invoker.getProduct("A358185");
    System.out.println ("Name:  "+prod.name);
    System.out.println ("Description:  "+prod.description);
    System.out.println ("Price:  "+prod.price);
 }
}

This is a very small amount of code, but it is capable of doing very real work. Be sure to check The Mind Electric web site (http://themindelectric.com/) for new releases of the GLUE product.

About the Author

Ethan Cerami is a Software Engineer at the Institute for Computational Biomedicine at Mount Sinai School of Medicine and an Adjunct Faculty at NYU's Department of Computer Science. He is also the author of Delivering Push (McGraw-Hill, 1998) and co-author with Simon St. Laurent of Building XML Applications (McGraw-Hill, 2000).

Source of this material

This is Chapter 6: WSDL Essentials from the book Web Services Essentials (ISBN:0-596-00224-6) written by Ethan Cerami, published by O'Reilly & Associates.

To access the full Table of Contents for the book





Page 4 of 4



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel