Anatomy of a Mapping File





Anatomy of a Mapping File

A mapping file can get to be pretty large. Some vendors may choose to support less verbose mapping files, that specify only the WSDL definitions that don't conform to the criteria for lightweight mapping. This "abbreviated mapping" can really reduce the amount of mapping information you must provide, but beware: It is not standardized, so abbreviated mapping files may not be portable across vendors. To ensure portability you should make your mapping as complete as you can.

I'll discuss individual elements in separate sections. Each should be a useful reference by itself, independent of other sections. In addition, sections do not depend on any one WSDL definition, but use a variety of WSDL documents to illustrate how each mapping element is used in practice.

It's important to remember that there is a one-to-one relationship between a JAX-RPC mapping file and a WSDL document, and that they must be packaged together in the same J2EE component archive file. The following snippet provides a rough skeleton of a JAX-RPC mapping file, showing only the primary elements. Use this skeleton to help understand the context in which the various mapping elements are declared.

<java-wsdl-mapping...>
  <package-mapping/>
  <java-xml-type-mapping/>
  <exception-mapping/>
  <service-interface-mapping/>
  <service-endpoint-interface-mapping>
      ...
      <service-endpoint-method-mapping/>
  </service-endpoint-interface-mapping>
</java-wsdl-mapping>

24.4.1 The java-wsdl-mapping Element

The java-wsdl-mapping element is the root of the JAX-RPC mapping file. It must be declared, and it will contain all other mapping elements. Listing 24-7 shows the root element of a JAX-RPC mapping file.

Listing 24-7 A java-wsdl-mapping Element
<?xml version='1.0' encoding='UTF-8' ?>
<java-wsdl-mapping
  xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:mh="http://www.Monson-Haefel.com/jwsbook/BookQuote"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
            http://www.ibm.com/webservices/xsd/j2ee_jaxrpc_mapping_1_1.xsd"
  version="1.1">
  ...
</java-wsdl-mapping>

24.4.2 The package-mapping Element

As I said in Section 24.2, the package-mapping element may be the only child of the root element required, if the WSDL document conforms to the criteria for lightweight mapping.

When you use generated stubs and dynamic proxies, a JAX-RPC compiler will use the package-mapping element to generate Java class and interface definitions for a variety of types defined in the WSDL document.

  • An endpoint interface for the WSDL portType element

  • An endpoint stub that implements the endpoint interface (when you're using JAX-RPC generated stubs)

  • A service interface for the WSDL service element

  • A service implementation for the service interface (when you're using JAX-RPC generated stubs)

  • A bean or plain Java class for each complex or simple type declared in the types element

  • Holder types for INOUT and OUT parameters of operation elements

Each of these classes and interfaces needs to be placed in one Java package or another—the package-mapping element dictates which. A package mapping looks like this:

<java-wsdl-mapping ...>
  <package-mapping>
    <package-type>com.jwsbook.jaxrpc</package-type>
    <namespaceURI>http://www.Monson-Haefel.com/jwsbook/BookQuote
    </namespaceURI>
  </package-mapping>
</java-wsdl-mapping>

The value of the package-type element is the name of the Java package and can be anything that fits standard Java naming rules. The value of namespaceURI is the XML namespace that should be mapped to the Java package name. In most cases the XML namespace you are mapping is the target namespace of the corresponding WSDL document, as in this snippet:

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="BookQuote"
 targetNamespace="http://www.Monson-Haefel.com/jwsbook/BookQuote"
 xmlns:mh="http://www.Monson-Haefel.com/jwsbook/BookQuote"
 xmlns="http://schemas.xmlsoap.org/wsdl/"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
 ...
</definitions>

If the WSDL document uses more than one namespace for generated types, you must declare a separate package-mapping element for each XML namespace. For example, the WSDL document in Listing 24-8 uses two namespaces, one for the target namespace of WSDL definitions and the other for XML schema types defined in the types element.

Listing 24-8 A WSDL Document That Requires Multiple package-mapping Elements
<?xml version='1.0' encoding='UTF-8' ?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:mh="http://www.Monson-Haefel.com/jwsbook/PurchaseOrder"
    targetNamespace="http://www.Monson-Haefel.com/jwsbook/PurchaseOrder"
    xmlns:soap="http://schemas.xmlsoap.org.wsdl/soap/"
    xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
    xmlns:po="http://www.Monson-Haefel.com/jwsbook/PO" >
  <types>
    <schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.Monson-Haefel.com/PO">
      <element name="purchaseOrder" type="po:PurchaseOrder"/>
      <complexType name="PurchaseOrder">
        <sequence>
          <element name="accountName" type="xsd:string"/>
          <element name="accountNumber" type="xsd:short"/>
          <element name="shipAddress" type="po:USAddress"/>
          <element name="billAddress" type="po:USAddress"/>
        </sequence>
        <attribute name="orderDate" type="xsd:date"/>
      </complexType>
      <complexType name="USAddress">
        <sequence>
          <element name="name" type="xsd:string"/>
          <element name="street" type="xsd:string"/>
          <element name="city" type="xsd:string"/>
          <element name="state" type="xsd:string"/>
          <element name="zip" type="xsd:string"/>
        </sequence>
      </complexType>
    </schema>
  </types>
  <message name="PurchaseOrderMessage">
    <part name="body" element="po:purchaseOrder"/>
  </message>
  <portType name="PurchaseOrder">
    <operation name="submitPurchaseOrder">
      <input message="mh:PurchaseOrderMessage"/>
    </operation>
  </portType>
  ...
</definitions>

In this case the XML namespace used for the WSDL definitions (message, portType, binding, service, and port) is different from the XML namespace used to define the XML schema types (PurchaseOrder and USAddress). Because the JAX-RPC compiler will create interfaces and classes for types from both namespaces, the mapping file must have a package-mapping element for each namespace, as shown in Listing 24-9.

Listing 24-9 A JAX-RPC Mapping File with Multiple package-mapping Elements
<java-wsdl-mapping ...>
  <package-mapping>
    <package-type>com.jwsbook.jaxrpc</package-type>
    <namespaceURI>http://www.Monson-Haefel.com/jwsbook/PurchaseOrder
    </namespaceURI>
  </package-mapping>
  <package-mapping>
    <package-type>com.jwsbook.jaxrpc.types</package-type>
    <namespaceURI>http://www.Monson-Haefel.com/jwsbook/PO</namespaceURI>
  </package-mapping>
</java-wsdl-mapping>

In this example the two XML namespaces are mapped to two different Java packages, but they don't have to be. You could map both namespaces to the same Java package, which is often more convenient.

24.4.3 The java-xml-type-mapping Element

The java-xml-type-mapping element is necessary when you are using complex or simple types, whether defined in the types element or imported from another XML document—with one exception. This element is not necessary if you're using standard XML schema built-in types with standard mapping to Java, as outlined in Section 15.2: Mapping XML Schema to Java. This element associates XML schema types with Java types.

As an example, let's say you want to map the WSDL document for the PurchaseOrder Web service to a JAX-RPC generated stub. This Web service uses One-Way Document/Literal messaging, and its message and portType elements are defined as in Listing 24-10.

Listing 24-10 A WSDL Document with java-xml-type-mapping Elements
<?xml version='1.0' encoding='UTF-8' ?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:po="http://www.Monson-Haefel.com/1ed/PurchaseOrder"
    xmlns:soap="http://schemas.xmlsoap.org.wsdl/soap/"
    xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
    xmlns:mh="http://www.Monson-Haefel.com/jwsbook/PurchaseOrder"
    targetNamespace="http://www.Monson-Haefel.com/jwsbook/PurchaseOrder">
  <types>
    <schema xmlns="http://www.w3.org/2001/XMLSchema"
      targetNamespace="http://www.Monson-Haefel.com/1ed/PurchaseOrder">
      <element name="purchaseOrder" type="po:PurchaseOrder"/>
      <complexType name="PurchaseOrder">
        <sequence>
          <element name="AcctName" type="xsd:string"/>
          <element name="ShipAddr" type="po:USAddress"/>
          <element name="ISBN" type="xsd:string" maxOccurs="unbounded"/>
        </sequence>
      </complexType>
      <complexType name="USAddress">
        <sequence>
          <element name="Street" type="xsd:string"/>
          <element name="City" type="xsd:string"/>
          <element name="State" type="xsd:string"/>
          <element name="Zip" type="xsd:string"/>
        </sequence>
      </complexType>
    </schema>
  </types>
  <message name="PurchaseOrderMessage">
    <part name="body" element="po:purchaseOrder"/>
  </message>
  <portType name="PurchaseOrder">
    <operation name="submitPurchaseOrder">
      <input message="mh:PurchaseOrderMessage"/>
    </operation>
  </portType>
  ...
</definitions>

In this case the mapping file will need a java-xml-type-mapping element for each complex type, one for PurchaseOrder and one for USAddress. The snippet in Listing 24-11 illustrates the mapping.

-11 XML Schema Types Mapped to Java Types
<java-to-xml-mapping>
   <class-type>com.jwsbook.jaxrpc.PurchaseOrder</class-type>
   <root-type-qname>po:PurchaseOrder</root-type-qname>
   <qname-scope>element</qname-scope>
   <variable-mapping>
      <java-variable-name>accountName</java-variable-name>
      <xml-element-name>AcctName</xml-element-name>
   </variable-mapping>
   <variable-mapping>
      <java-variable-name>shipAddress</java-variable-name>
      <xml-element-name>ShipAddr</xml-element-name>
   </variable-mapping>
   <variable-mapping>
      <java-variable-name>isbn</java-variable-name>
      <xml-element-name>ISBN</xml-element-name>
   </variable-mapping>
</java-to-xml-mapping>

<java-to-xml-mapping>
<class-type>com.jwsbook.jaxrpc.USAddress</class-type>
   <root-type-qname>po:USAddress</root-type-qname>
   <qname-scope>complexType</qname-scope>
   <variable-mapping>
      <java-variable-name>street</java-variable-name>
      <xml-element-name>Street</xml-element-name>
   </variable-mapping>
   <variable-mapping>
      <java-variable-name>city</java-variable-name>
      <xml-element-name>City</xml-element-name>
   </variable-mapping>
   <variable-mapping>
      <java-variable-name>state</java-variable-name>
      <xml-element-name>State</xml-element-name>
   </variable-mapping>
   <variable-mapping>
      <java-variable-name>zip</java-variable-name>
      <xml-element-name>Zip</xml-element-name>
   </variable-mapping>
</java-to-xml-mapping>

24.4.4 The exception-mapping Element

An exception-mapping element maps a WSDL fault message to a Java exception class.

For example, the WSDL document in Listing 24-12 declares two fault messages that can be generated for the BookQuote Web service.

-12 A WSDL Document That Declares Fault Messages
<definitions name="BookQuote"
    targetNamespace="http://www.Monson-Haefel.com/jwsbook/BookQuote"
    xmlns:mh="http://www.Monson-Haefel.com/jwsbook/BookQuote"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
  ...
  <message name="InvalidIsbnFault" >
    <part name="message" type="xsd:string"/>
  </message>
  <message name="SecurityFault" >
    <part name="message" type="xsd:string"/>
  </message>
  <portType name="BookQuote">
    <operation name="getBookPrice">
      <input message="mh:BookQuote_getBookPrice"/>
      <output message="mh:BookQuote_getBookPriceResponse"/>
      <fault name="InvalidIsbnFault" message="mh:InvalidIsbnFault" />
      <fault name="InvalidIsbnFault" message="mh:SecurityFault" />
    </operation>
  </portType>
  ...
</definitions>

Based on this definition, two exception-mapping elements should be declared as in Listing 24-13.

-13 Fault Messages Mapped to Java Exception Types
<java-xml-mapping ...
   xmlns:mh="http://www.Monson-Haefel.com/jwsbook/BookQuote"… >

   <package-mapping/>
   <exception-mapping>
      <exception-type>com.jwsbook.jaxrpc.InvalidIsbnException</exception-type>
      <wsdl-message>mh:InvalidIsbnFault</wsdl-message>
   </exception-mapping>
   <exception-mapping>
      <exception-type>com.jwsbook.jaxrpc.SecurityException</exception-type>
      <wsdl-message>mh:SecurityFault</wsdl-message>
   </exception-mapping>
   ...
</java-xml-mapping>

Notice that the class name of the exception ends with Exception rather than Fault. This ability to rename the exceptions to be more Java-friendly is a nice advantage of using the exception-mapping element, and might be one reason for defining a heavyweight mapping file even if it's not required.

As you know, a WSDL fault message can define only a single part element. In the preceding example, the WSDL fault messages contained a single XML schema built-in type (xsd:string), which makes for a fairly straightforward mapping. When a fault declares a part that refers to an XML schema complex type, however, you can specify in the mapping file an additional element, constructor-parameter-order, which dictates the order of parameters in the constructor of the exception class. This element can help the compiler create an exception class that relies on a complex type like the one in the following snippet.

<types>
  <xsd:schema
   targetNamespace="http://www.Monson-Haefel.com/jwsbook/BookQuote">
    <xsd:complexType name="InvalidIsbnType">
       <xsd:sequence>
         <xsd:element name="offending-value" type="xsd:string"/>
         <xsd:element name="conformance-rules" type="xsd:string"/>
       </xsd:sequence>
    </xsd:complexType>
  </xsd:schema>
</types>
...
<message name="getBookPriceFault">
  <part name="fault" type="mh:InvalidIsbnType" />
</message>

The exception-mapping element can specify which element of InvalidIsbn Type is to be the first parameter passed to the exception's constructor and which is to be second, as here.

<java-xml-mapping ...
   xmlns:mh="http://www.Monson-Haefel.com/jwsbook/BookQuote"... >
   <package-mapping/>
   <exception-mapping>
      <exception-type>com.jwsbook.jaxrpc.InvalidIsbnException</exception-type>
      <wsdl-message>mh:InvalidIsbnFault</wsdl-message>
      <constructor-parameter-order>
         <element-name>conformance-rules</element-name>
         <element-name>offending-value</element-name>
      </constructor-parameter-order>
   </exception-mapping>
   ...
</java-xml-mapping>

The JAX-RPC compiler would create a constructor for the corresponding Java exception class with a constructor as follows.

public InvalidIsbnException(String conformanceRules,
                            String offendingValue);

24.4.5 The service-interface-mapping Element

The service-interface-mapping element maps a WSDL service definition to a custom JAX-RPC service interface type. It also specifies the names and types of the getPortName() methods, which return references to generated endpoint stubs at runtime. To illustrate I'll use a WSDL document that defines two different ports, one that uses RPC/Encoded messaging and another that uses Document/Literal messaging, as in Listing 24-14.

-14 A WSDL Document That Supports Two Messaging Modes
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="BookQuote"
    targetNamespace="http://www.Monson-Haefel.com/jwsbook/BookQuote"
    xmlns:mh="http://www.Monson-Haefel.com/jwsbook/BookQuote"  …>
  <portType name="BookQuote">
    <operation name="getBookPrice">
      <input message="mh:BookQuote_getBookPrice"/>
      <output message="mh:BookQuote_getBookPriceResponse"/>
    </operation>
  </portType>
  <binding name="BookQuoteBinding_docLit" type="mh:BookQuote">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"
                  style="document"/>
     <operation name="getBookPrice">
      <soap:operation soapAction=""/>
      <input>
        <soap:body use="literal" />
      </input>
      <output>
        <soap:body use="literal" />
      </output>
    </operation>
  </binding>
  <binding name="BookQuoteBinding_rpcEnc" type="mh:BookQuote">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"
                  style="rpc"/>
    <operation name="getBookPrice">
      <soap:operation soapAction=""/>
      <input>
        <soap:body
          encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
          use="encoded"
          namespace=
            "http://www.Monson-Haefel.com/jwsbook/BookQuote/BookQuote"/>
      </input>
      <output>
        <soap:body
          encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
          use="encoded"
          namespace=
            "http://www.Monson-Haefel.com/jwsbook/BookQuote/BookQuote"/>
      </output>
    </operation>
  </binding>
  <service name="BookQuoteService">
    <port name="BookQuotePort_docLit" binding="mh:BookQuoteBinding_docLit">
      <soap:address
       location=
         "http://www.Monson-Haefel.com/jwsbook/doclit/BookQuoteService"/>
    </port>
    <port name="BookQuotePort_rpcEnc" binding="mh:BookQuoteBinding_rpcEnc ">
      <soap:address
       location=
         "http://www.Monson-Haefel.com/jwsbook/rpcenc/BookQuoteService"/>
    </port>
  </service>
</definitions>

The WSDL document defines a single service definition, BookQuoteService, that declares two separate port elements. The first, BookQuotePort_docLit, defines a Web service that uses the BookQuote portType with a Document/Literal binding. The second, BookQuotePort_rpcEnc, defines a Web service that also uses the BookQuote portType but an RPC/Encoded binding. This would be done to give the Web service's clients a choice of messaging modes.

Using a service-interface-mapping element, we can map the BookQuoteService to a JAX-RPC service interface that contains two getPortName() methods, one for each WSDL port definition, as in Listing 24-15.

-15 Mapping the Two Messaging Modes to Java
<java-wsdl-mapping
  xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:mh="http://www.Monson-Haefel.com/jwsbook/BookQuote" ...>
  <package-mapping/>
  <java-xml-type-mapping/>
  <service-interface-mapping>
    <service-interface>com.jwsbook.jaxrpc.BookQuoteService</service-interface>
    <wsdl-service-name>mh:BookQuoteService</wsdl-service-name>
    <port-mapping>
      <port-name>mh:BookQuotePort_docLit</port-name>
      <java-port-name>DocLitPort</java-port-name>
    </port-mapping>
    <port-mapping>
      <port-name>mh:BookQuotePort_rpcEnc</port-name>
      <java-port-name>RpcEncPort</java-port-name>
    </port-mapping>
  </service-interface-mapping>
  ...
</java-wsdl-mapping>

The service-interface element simply declares the fully qualified class name of the Java interface that will represent the WSDL service definition. The package name of the service interface should match the package name declared in the package-mapping element.

The port-mapping elements assign a name that will be used for each WSDL port in the getPortName() methods. The port-name element provides the fully qualified XML name of the port definition, and java-port-name provides the port-name part of the getPortName() method signature. Listing 24-16 shows how this mapping is manifested in a Java service interface definition.

-16 The Service Interface That Supports Two Messaging Modes
package com.jwsbook.jaxrpc;

public interface BookQuoteService extends javax.xml.rpc.Service {

    public BookQuote getDocListPort();
    public BookQuote getRpcEncPort();

}

You can use any name you want for the java-port-name element, but it's a good practice to use something descriptive.

24.4.6 The service-endpoint-interface-mapping Element

The service-endpoint-interface-mapping element maps a JAX-RPC endpoint interface to a specific set of WSDL portType and binding definitions. This element helps the JAX-RPC compiler generate the proper endpoint stub and endpoint interfaces. It also details how WSDL operation and message part definitions map to endpoint methods.

As an example, we can take the RPC/Literal WSDL definition for the BookQuote Web service, shown in Listing 24-17, and map it using the service-endpoint-interface-mapping.

-17 A WSDL Document That Defines a Service Endpoint Interface
<definitions name="BookQuote"
    targetNamespace="http://www.Monson-Haefel.com/jwsbook/BookQuote"
    xmlns:mh="http://www.Monson-Haefel.com/jwsbook/BookQuote"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
  <portType name="BookQuote">
    <operation name="getBookPrice">
      <input message="mh:BookQuote_getBookPrice"/>
      <output message="mh:BookQuote_getBookPriceResponse"/>
      <fault name="InvalidIsbnFault" message="mh:InvalidIsbnFault" />
    </operation>
  </portType>
  <binding name="BookQuoteBinding" type="mh:BookQuote">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"
                  style="rpc"/>
    <operation name="getBookPrice">
      <soap:operation soapAction=""/>
      <input>
        <soap:body
        use="literal"
        namespace="http://www.Monson-Haefel.com/jwsbook/BookQuote/BookQuote"/>
      </input>
      <output>
        <soap:body
        use="literal"
        namespace="http://www.Monson-Haefel.com/jwsbook/BookQuote"/>
      </output>
      <fault name="mh:InvalidIsbnFault">
        <soap:fault
        use="literal"
      </fault>
    </operation>
  </binding>
  ...
</definitions>

The service-endpoint-interface-mapping element for this WSDL port Type and binding pair would look like Listing 24-18.

-18 Mapping the Service Endpoint Interface to Java
<?xml version='1.0' encoding='UTF-8' ?>
<java-wsdl-mapping
  xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:mh="http://www.Monson-Haefel.com/jwsbook/BookQuote"...>
  <package-mapping/>
  <java-xml-type-mapping/>
  <exception-mapping/>
  <service-interface-mapping/>
  <service-endpoint-interface-mapping>
    <service-endpoint-interface>com.jwsbook.jaxrpc.BookQuote
    </service-endpoint-interface>
    <wsdl-port-type>mh:BookQuote</wsdl-port-type>
    <wsdl-binding>mh:BookQuoteBinding</wsdl-binding>
    <service-endpoint-method-mapping>
      <!-- method mapping goes here -->
    </service-endpoint-method-mapping>
  </service-endpoint-interface-mapping>
</java-wsdl-mapping>

The service-endpoint-interface element declares the fully qualified Java class name of the endpoint interface that the compiler should generate.

The wsdl-port-type and wsdl-binding elements define the fully qualified XML names of the WSDL portType definition and the binding definition associated with the endpoint interface, respectively.

The service-endpoint-method-mapping element is fairly complex. It's responsible for mapping a WSDL operation and its message part definitions to a specific method signature in the endpoint interface. For example, suppose the WSDL message and portType definitions for the BookQuote Web service looked like these:

<message name="BookQuote_getBookPrice">
  <part name="isbn" type="xsd:string"/>
</message>
<message name="BookQuote_getBookPriceResponse">
  <part name="result" type="xsd:float"/>
</message>
<message name="InvalidIsbnFault" >
  <part name="message" type="xsd:string"/>
</message>
<portType name="BookQuote">
  <operation name="getBookPrice">
    <input message="mh:BookQuote_getBookPrice"/>
    <output message="mh:BookQuote_getBookPriceResponse"/>
    <fault name="InvalidIsbnFault" message="mh:InvalidIsbnFault" />
  </operation>
</portType>

Then the service-endpoint-method-mapping element in the mapping file would look like this:

<service-endpoint-interface-mapping>
  <service-endpoint-interface>com.jwsbook.jaxrpc.BookQuote
  </service-endpoint-interface>
  <wsdl-port-type>mh:BookQuote</wsdl-port-type>
  <wsdl-binding>mh:BookQuoteBinding</wsdl-binding>
  <service-endpoint-method-mapping>
    <java-method-name>getBookPrice</java-method-name>
    <wsdl-operation>mh:getBookPrice</wsdl-operation>
    <method-param-parts-mapping>
      <param-position>0</param-position>
      <param-type>java.lang.String</param-type>
      <wsdl-message-mapping>
        <wsdl-message>mh:BookQuote_getBookPriceRequest</wsdl-message>
        <wsdl-message-part-name>isbn</wsdl-message-part-name>
        <parameter-mode>IN</parameter-mode>
      </wsdl-message-mapping>
    </method-param-parts-mapping>
    <wsdl-return-value-mapping>
      <method-return-value>float</method-return-value>
      <wsdl-message>mh:BookQuote_getBookPriceResponse</wsdl-message>
      <wsdl-message-part-name>result</wsdl-message-part-name>
    </wsdl-return-value-mapping>
  </service-endpoint-method-mapping>
 </service-endpoint-interface-mapping>

The service-endpoint-method-mapping element has four important child elements: java-method-name, wsdl-operation, method-param-parts-mapping, and wsdl-return-value-mapping.

The java-method-name element simply declares the Java method name for a specific WSDL operation, and the wsdl-operation element provides the fully qualified XML name of the WSDL operation being mapped.

A method-param-parts-mapping element is declared for every part definition defined by the input message of the WSDL operation. The getBookPrice WSDL operation's input message has only one part, so we need only one method-param-parts-mapping element, as shown in the following snippet.

<method-param-parts-mapping>
  <param-position>0</param-position>
  <param-type>java.lang.String</param-type>
  <wsdl-message-mapping>
     <wsdl-message>mh:BookQuote_getBookPriceRequest</wsdl-message>
     <wsdl-message-part-name>isbn</wsdl-message-part-name>
     <parameter-mode>IN</parameter-mode>
  </wsdl-message-mapping>
</method-param-parts-mapping>

The param-position element specifies the position that the Java parameter will have in the method signature (positions numbered from zero). The param-type declares the Java type of the parameter; in this case we're mapping the simple XML schema built-in type xsd:string to the Java type java.lang.String. If the part were a complex type, then you would map a Java class name to that complex type in the java-xml-type-mapping element, at the beginning of the mapping file.

The wsdl-message-mapping element pinpoints the WSDL message and part definition that's being mapped, declaring the fully qualified XML name of the message definition, while the wsdl-message-part-name declares the name of the part.

The parameter-mode element indicates whether the parameter is an IN, INOUT, or OUT parameter. Any INOUT and OUT parameters will be mapped to JAX-RPC holder types that wrap around the Java types defined by the param-type elements, in accordance with the rules discussed in Section 15.3: Holders.

The wsdl-return-value-mapping element is similar to the method-param-parts-mapping element. There are two differences: It can be declared only once for each operation because a Java method can have only one return value, and its parameter mode is assumed to be OUT. Compare and contrast wsdl-return-value-mapping with method-param-parts-mapping in the following snippet.

<service-endpoint-method-mapping>
  <java-method-name>getBookPrice</java-method-name>
  <wsdl-operation>mh:getBookPrice</wsdl-operation>
  <method-param-parts-mapping>
    <param-position>0</param-position>
    <param-type>java.lang.String</param-type>
    <wsdl-message-mapping>
      <wsdl-message>mh:BookQuote_getBookPriceRequest</wsdl-message>
      <wsdl-message-part-name>isbn</wsdl-message-part-name>
      <parameter-mode>IN</parameter-mode>
    </wsdl-message-mapping>
  </method-param-parts-mapping>
  <wsdl-return-value-mapping>
    <method-return-value>float</method-return-value>
    <wsdl-message>mh:BookQuote_getBookPriceResponse</wsdl-message>
    <wsdl-message-part-name>result</wsdl-message-part-name>
  </wsdl-return-value-mapping>
</service-endpoint-method-mapping>

The service-endpoint-method-mapping element can be especially useful when WSDL operation definitions don't map naturally to Java methods. For example, a portType can quite legally define two operations that have the same name and the same input messages but different output messages, but the Java programming language doesn't allow the equivalent method overloading. Two methods can't have the same name and different return types unless they also have different parameters. In the following snippet, the WSDL definition defines two getBookPrice operations, one whose output is an xsd:float and another whose output is an xsd:string.

<message name="IsbnRequest">
  <part name="isbn" type="xsd:string"/>
</message>
<message name="FloatResponse">
  <part name="result" type="xsd:float"/>
</message>
<message name="StringResponse" >
  <part name="result" type="xsd:string"/>
</message>
<portType name="BookQuote">
  <operation name="getBookPrice">
    <input message="mh:IsbnRequest"/>
    <output message="mh:FloatResponse"/>
  </operation>
  <operation name="getBookPrice">
    <input message="mh:IsbnRequest"/>
    <output message="mh:StringResponse"/>
  </operation>
</portType>

If the JAX-RPC compiler mapped this directly to a Java endpoint, it would create an illegal interface definition, in which methods are overloaded by return type.

public interface BookQuote extends java.rmi.Remote {

    public float getBookPrice(String isbn):
    public String getBookPrice(String isbn); // Illegal overloading
}

To avoid this conflict, you can provide different names for the two Java methods in the service-endpoint-method-mapping element, as in the following snippet.

<service-endpoint-method-mapping>
  <java-method-name>getBookPriceFloat</java-method-name>
  <wsdl-operation>mh:getBookPrice</wsdl-operation>
  <method-param-parts-mapping>
    <param-position>0</param-position>
    <param-type>java.lang.String</param-type>
    <wsdl-message-mapping>
      <wsdl-message>mh:IsbnRequest</wsdl-message>
      <wsdl-message-part-name>isbn</wsdl-message-part-name>
      <parameter-mode>IN</parameter-mode>
    </wsdl-message-mapping>
  </method-param-parts-mapping>
  <wsdl-return-value-mapping>
    <method-return-value>float</method-return-value>
    <wsdl-message>mh:FloatResponse</wsdl-message>
    <wsdl-message-part-name>result</wsdl-message-part-name>
  </wsdl-return-value-mapping>
</service-endpoint-method-mapping>
<service-endpoint-method-mapping>
  <java-method-name>getBookPriceString</java-method-name>
  <wsdl-operation>mh:getBookPrice</wsdl-operation>
  <method-param-parts-mapping>
    <param-position>0</param-position>
    <param-type>java.lang.String</param-type>
    <wsdl-message-mapping>
      <wsdl-message>mh:IsbnRequest</wsdl-message>
      <wsdl-message-part-name>isbn</wsdl-message-part-name>
      <parameter-mode>IN</parameter-mode>
    </wsdl-message-mapping>
  </method-param-parts-mapping>
  <wsdl-return-value-mapping>
    <method-return-value>java.lang.String</method-return-value>
    <wsdl-message>mh:StringResponse</wsdl-message>
    <wsdl-message-part-name>result</wsdl-message-part-name>
  </wsdl-return-value-mapping>
</service-endpoint-method-mapping>

Given the above mapping, the compiler will generate methods named getBookPriceFloat() and getBookPriceString(), and dodge the overloading problem.


     Python   SQL   Java   php   Perl 
     game development   web development   internet   *nix   graphics   hardware 
     telecommunications   C++ 
     Flash   Active Directory   Windows