Main Page

Previous Section Next Section

Data Types and Serialization

Let us revisit some object-oriented concepts. An object at any time has state. This state, represented by its member variables at that time, is the object's snapshot. The definition of the object is the class file or compiled representation. An object with no member variables—that is, no state—is essentially just a utility that does something useful every time its methods are invoked. It may create other objects and change their states, but the scope of such secondary objects is limited to the method.

To do a remote procedure call, something representing state must be sent over the wire, and something representing state must be returned. Sending objects over the network is not trivial, since the network is not aware of objects; it supports only bit transmission.

The mechanism used to change the objects into a format that can be transmitted over the network is called marshalling, and reconstructing the objects from this format is called unmarshalling. Marshalling over the wire requires object state to be extracted and sent in a well-defined format. Unmarshalling requires that the format be known, for reconstruction to take place. To marshal and unmarshal successfully, both sides in the exchange must use the same protocol to encode and decode object structure and data. For example, RMI Java uses Java serialization to marshal and unmarshal objects over Java Remote Method Protocol (JRMP). CORBA uses IIOP, DCOM uses ORPC, and Gemstone uses SRP.

In summary, four things are required between communication parties in different address spaces:

  1. An agreement on the data format

  2. An agreement on the mechanism for transforming and reconstructing object state into this format

  3. An agreement on the protocol for communication between objects

  4. An agreement on the transport protocol

XML helps in achieving item 1, XML schemas and SOAP with 2 and 3, and HTTP (and others in the IP family of protocols) with 4.

So how is this relevant to JAX-RPC? JAX-RPC defines

This is significant, because JAX-RPC provides a standard for vendors to implement and makes developer code vendor-neutral, much the way any of the other Java specifications do. Just as developers write a J2EE application and expect it to behave the same across J2EE-compliant application servers from multiple vendors, JAX-RPC applications will behave the same across JAX-RPC runtimes.

This does not mean that a JAX-RPC client can call only a JAX-RPC service and a JAX-RPC service can be used only by a JAX-RPC client. An application could still use a JAX-RPC client to invoke a .NET service and a .NET client to invoke a JAX-RPC service, as we will demonstrate later. As Figure 10.2 shows, because the data format, object communication protocol, and transport protocol are platform- and vendor-implementation independent, the application can be accessed by any client on any platform, as long as it uses these standards. The data type mapping and serialization rules defined by JAX-RPC are useful when the JAX-RPC runtime is being used on the Java platform at the client or server end.

Click To expand
Figure 10.2: JAX-RPC client-server interaction

From an RPC perspective, if the client and service are written in Java, the runtime needs to know the following information:

  1. The endpoint of the service—that is, where to invoke the service

  2. The method name and signature—that is, what to invoke

  3. How to marshal Java data types and objects into an XML format that can be transmitted over the wire to invoke the method

  4. How to unmarshal the incoming XML into Java data types and objects to process the results of that operation, if any

Java-to-XML Marshalling

While JAX-RPC does not define the actual marshalling mechanism, it does define the input and output types that result from that marshalling. Vendors write the marshalling code as part of their implementations.

In JAX-RPC, marshalling is different from the standard Java serialization mechanism, where all nontransient fields in the class are automatically serialized. JAX-RPC defines a standard set of Java types as method arguments and return types, meaning that a JAX-RPC—compliant system will provide the ready-to-use serializers and deserializers for these types:

  1. All Java primitives, with the exception of a char (int, float, long, short, double, byte, Boolean). A char is treated as a String, since XML schemas have no char type primitive (see Appendix A).

  2. An object that is an instance of

    • java.lang.String

    • java.util.Date

    • java.util.Calendar

    • java.math.BigInteger

    • java.math.BigDecimal

  3. An object that is an instance of a class that conforms to the following restrictions:

    • It should conform to the JavaBean specification, so that its variables can be easily accessed.

    • It should not be a Remote object (i.e., should not implement java.rmi.Remote).

    • It should have a default no arguments constructor.

    These are important, because any other class is passed between the client and the server. For example, if a java.util.Map of com.flutebank.Account objects must be passed from the client to the server, a pluggable serializer and deserializer pair must be written. This is explored later in this chapter.

  4. An array (with the caveat that it must contain bytes or a supported type)

  5. A java.lang.Exception class

The above rules differ from the standard Java serialization requirements. Table 10.1 lists the details for the same class to be used across an RMI/RMI-IIOP application as well as a JAX-RPC application. This is relevant where an existing EJB, RMI, or RMI-IIOP object must expose itself directly as a JAX-RPC service and the code must be reused across these interfaces.

Table 10.1: Portability across JAX-RPC and RMI

JAX-RPC

Java serialization

A portable value object

Should not extend Remote.

Can extend Remote. It is treated as an remote object and passed by reference.

Should not implement Remote.

Serializable not required.

Serializable required.

Should implement Serializable.

transient fields are not serialized.

transient fields are not serialized.

transient fields are not serialized.

static fields are serialized.

static fields are not serialized.

Should not contain static fields.

All public variables are serialized.

public transient variables are not serialized.

Should not contain any public transient variables.

Only private, protected, package-level fields that have get/set methods are serialized.

Get/set methods are not required. Private, protected, package-level fields are still serialized.

Should have get/set methods for all private, protected, package-level fields.

Bean properties are serialized.

Bean properties are serialized.

Can have bean properties with get/set methods.

Once the parameter types have been defined, rules and a standard mechanism to map these data types from Java to XML must also be defined. JAX-RPC does this, as Table 10.2 shows.

Table 10.2: Java-to-XML Data Type Mapping

Java type

XML type

Boolean

xsd:boolean

Byte

xsd:byte

Short

xsd:short

Int

xsd:int

Long

xsd:long

Float

xsd:float

Double

xsd:double

byte[]

xsd:base64Binary

Byte[]

xsd:base64Binary

java.lang.String

xsd:string

java.math.BigInteger

xsd:integer

java.math.BigDecimal

xsd:decimal

java.util.Calendar

xsd:dateTime

java.util.Date

xsd:dateTime

javax.xml.namespace.Qname

xsd:QName

JavaBean class whose properties are any supported

Java data type or another valid JavaBean

XML schema sequence of elements

Array of any of above

SOAP array

XML-to-Java Unmarshalling

To invoke a procedure on an object with incoming XML data, an implementation must map XML data types into Java data types. This is identical to Table 10.2, with some differences explained in Tables 10.3a and 3b. XML type is declared as nillable in the schema, then it maps to its corresponding Java wrapper (primitives in Java cannot be null).

Table 10.3a: XML-to-Java Data Type Mapping for Basic Types

XML type

Java type

When declared as nillable

xsd:boolean

Boolean

java.lang.Boolean

xsd:byte

Byte

java.lang.Byte

xsd:short

Short

java.lang.Short

xsd:int

Int

java.lang.Integer

xsd:long

Long

java.lang.Long

xsd:float

Float

java.lang.Float

xsd:double

double

java.lang.Double

xsd:base64Binary

byte[]

 

xsd:hexBinary

byte[]

 

xsd:string

java.lang.String

 

xsd:integer

java.math.BigInteger

 

xsd:decimal

java.math.BigDecimal

 

xsd:dateTime

java.util.Calendar

 

xsd:Qname

javax.xml.namespace.Qname

 

SOAP Bindings and Encoding

In Chapter 4, we looked at SOAP encoding in detail. Encoding refers to how data is serialized and sent over the wire. The parties exchanging messages have to agree on one rule to ensure that both correctly interpret the message sent from the other side. They can either agree beforehand, using a predefined encoding scheme, or use an XML schema directly in the data to define the data types. The message with the former notation is said to be an encoded message; the latter is said to be a literal message.

SOAP encoding refers to the rules defined by the SOAP specification that the parties can follow to interpret the contents of the Body element. SOAP defines an encoding scheme, also referred to as Section 5 encoding (since it is specified in section 5 of the SOAP specifications). It outlines a schema (http://schemas.xmlsoap.org/soap/encoding/) containing certain basic data types that participants in the conversation can use to describe the elements in the body of the SOAP message. This encoding is not mandatory, and there is no default.

In Chapter 4, we also looked at the use of the encodingStyle attribute and the use of simple and compound types. To recall, the encodingStyle attribute in the SOAP message can be used to indicate the encoding in use. For example, the message below indicates that SOAP encodings are in use:

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:enc="http://
schemas.xmlsoap.org/soap/encoding/" xmlns:ns0="http://www.flutebank.com/xml"
env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:getLastPayment>
    <vendor xsi:type="enc:string">my cable tv provider</vendor>
</ns0:getLastPayment>
</env:Body>
</env:Envelope>

The message shows that the vendor element is of type enc:string defined in the encoding schema, represented by the encodingStyle attribute. The receiver of this message, processing the vendor element, knows it is a SOAP-encoded string, which it can then translate into the language in which the service is implemented.

The SOAP specification does not define any language bindings for the data types described by its encoding schema. Instead, the types are generic enough to model some of the typical data types found in Java and most other programming languages. JAX-RPC defines how the simple types in the SOAP encoding are mapped to Java, as per Table 10.4.

Note that the data types in Table 10.4 are the same as the nillable types in Table 10.3a, because they map to the same underlying basic XML schema types. Of particular interest is the Array type, which maps to Java arrays. In the previous extract, if the SOAP body contained something like the following, it would be mapped to an array of String[] objects in the Java side by JAX-RPC, and vice versa:

Table 10.3b: XML-to-Java Data Type Mapping

XML construct

Java construct

ComplexType

JavaBeans class with the same name.

Its properties are mapped from the element's name and type.

Complex types derived by extension are mapped into classes with similar hierarchies.

  • Example

   <complexType name="PaymentConfirmation">
       <sequence>
             <element name="confirmationNum" type="int"/>
             <element name="payee" type="string"/>
             <element name="amt" type="double"/>
       </sequence>
   </complexType>

   public class PaymentConfirmation {
       private int confirmationNum;
       private String payee;
       private double amt;
       public PaymentConfirmation() {
       }

       public PaymentConfirmation(int confirmationNum,
                                 java.lang.String payee, double amt) {
           this.confirmationNum = confirmationNum;
           this.payee = payee;
           this.amt = amt;
       }

   // getXXX/setXXX methods for each member property
   }

XML construct

Java construct

Enumerations

A Java class with the same name as the enumeration. The class must contain

  1. The enumerated values as members of the enumeration type

  2. A getValue method that returns the current value

  3. Two static methods for each label

  • Example

   <simpleType name="PaymentDetail" >
       <restriction base="xsd:string" >
           <enumeration value="checking"/>
           <enumeration value="saving"/>
           <enumeration value="brokerage"/>
       </restriction>
   </simpleType>

   public class PaymentDetail implements Serializable {
       private String value;
       public static final String _checkingString = "checking";
       public static final String _savingString = "saving";
       public static final String _brokerageString = "brokerage";

       public static final String _checking = new String
                                        (_checkingString);
       public static final String _saving = new String(_savingString);
       public static final String _brokerage = new String
                                        (_brokerageString);

       public static final PaymentDetail checking =
                                        new PaymentDetail(_checking);
       public static final PaymentDetail saving = new PaymentDetail
                                        (_saving);
       public static final PaymentDetail brokerage =
                                        new PaymentDetail(_brokerage);
       protected PaymentDetail(String value) {
           this.value = value;
       }

       public String getValue() {
           return value;
       }

       public static PaymentDetail fromValue(String value)
           throws IllegalStateException {
           if (checking.value.equals(value)) {
               return checking;
           } else if (saving.value.equals(value)) {
               return saving;
           } else if (brokerage.value.equals(value)) {
               return brokerage;
           }
           throw new IllegalArgumentException();
       }

       public static PaymentDetail fromString(String value)
           throws IllegalStateException {
           if (value.equals(_checkingString)) {
               return checking;
           } else if (value.equals(_savingString)) {
               return saving;
           } else if (value.equals(_brokerageString)) {
               return brokerage;
           }
           throw new IllegalArgumentException();
           }
       }
   // other methods not shown
   }

Table 10.4: Mapping of SOAP Simple Types to Java

SOAP-encoded simple type

Java type

String

java.lang.String

Boolean

java.lang.Boolean

Float

java.lang.Float

Double

java.lang.Double

Decimal

java.math.BigDecimal

Int

java.lang.Integer

Short

java.lang.Short

Byte

java.lang.Byte

Base64

byte[]

Array

Java array

<ns0:getLastPayment>
<vendor enc:arrayType="xsd:string[4]" xsi:type="enc:Array">
   <item xsi:type="xsd:string">AT&T</item>
   <item xsi:type="xsd:string">Sprint PCS</item>
   <item xsi:type="xsd:string">Flute Electric Co</item>
</vendor>
</ns0:getLastPayment>

While mapping arrays, the type of the array is determined from the schema type. The size is determined at runtime rather than at declaration time. JAX-RPC also supports multidimensional arrays, where the types are supported JAX-RPC types. Listing 10.1 shows how a multidimensional array of application-defined PaymentDetail objects may be mapped on the wire using SOAP encoding:

Listing 10.1: A multidimensional array of application-defined PaymentDetail objects mapped on the wire using SOAP encoding
Start example
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns0="http://www.flutebank.com/xml"
// other namespaces >
<env:Body>
// other XML
<ns0:ArrayOfArrayOfPaymentDetail id="ID1" xsi:type="enc:Array"
enc:arrayType="ns0:PaymentDetail[2,2]">
           <item href="#ID2"/>
           <item href="#ID3"/>
           <item href="#ID4"/>
           <item href="#ID5"/>
</ns0:ArrayOfArrayOfPaymentDetail>
     <ns0:PaymentDetail id="ID2" xsi:type="ns0:PaymentDetail">
           <date xsi:type="xsd:dateTime">2002-08-26T21:17:37.678Z</date>
           <account xsi:type="xsd:string">Credit</account>
           <payeeName xsi:type="xsd:string">Digital Credit Union</payeeName>
           <amt xsi:type="xsd:double">2000.0</amt>
     </ns0:PaymentDetail>

     <ns0:PaymentDetail id="ID3" xsi:type="ns0:PaymentDetail">
           <date xsi:type="xsd:dateTime">2002-08-26T21:17:37.678Z</date>
           <account xsi:type="xsd:string">Credit</account>
           <payeeName xsi:type="xsd:string">Auto Loan Company</payeeName>
           <amt xsi:type="xsd:double">299.0</amt>
     </ns0:PaymentDetail>

     <ns0:PaymentDetail id="ID4" xsi:type="ns0:PaymentDetail">
           <date xsi:type="xsd:dateTime">2002-08-26T21:17:37.678Z</date>
           <account xsi:type="xsd:string">Credit</account>
           <payeeName xsi:type="xsd:string">AT&amp;T Wireless</payeeName>
           <amt xsi:type="xsd:double">20.0</amt>
     </ns0:PaymentDetail>

     <ns0:PaymentDetail id="ID5" xsi:type="ns0:PaymentDetail">
           <date xsi:type="xsd:dateTime">2002-08-26T21:17:37.678Z</date>
           <account xsi:type="xsd:string">Credit</account>
           <payeeName xsi:type="xsd:string">AT&amp;T Long distance</payeeName>
           <amt xsi:type="xsd:double">12.0</amt>
     </ns0:PaymentDetail>
</env:Body>
</env:Envelope>

End example

In Chapter 4, we introduced the concept of RPC/document style. Recall that a SOAP message on the wire can be represented in either in RPC style or document style, which affects the body of the message. In RPC style, the client invokes a method on the server, by sending in the body of the SOAP message all information necessary for that method's execution. It receives a response in the same fashion. All SOAP messages shown till now in this chapter have been in RPC style.

In document style, the client and server communicate using XML documents. The client sends an XML document such as a purchase order; the server does something with it and returns an XML document such as an invoice as a result (Figure 10.3).

Click To expand
Figure 10.3: (a) RPC style. (b) Document style.

Thus, based on the style (RPC or document) and use (encoded or literal), four combinations result:

  • RPC/encoded

  • RPC/literal

  • Document/encoded

  • Document/literal

In Chapter 5, we looked at how WSDL could represent these combinations using the style and use attributes of the binding element. Let us elaborate on that with a detailed example. The WSDL extract below shows a sample schema and message extracts. The schema has two elements, Amount and details, and a custom type, PaymentDetail. The message element shown has four parts: part1, which is of type PaymentDetail; part2, which is of type int; part3, which is a simple element Amount; and part4, which is an element of complex type PaymentDetail. Table 10.5 compares the combinations.

Table 10.5: Examples of RPC/Encoded, RPC/Literal, Document/Literal, and Document/Encoded Combinations

Style

RPC/encoded

  • WSDL

   <operation name="schedulePayment" style="rpc" ... >
   <input>
   <soap:body parts="part1 part2"
             use="encoded"
             encoding= "http://schemas.xmlsoap.org/soap/encoding/"
    namespace="(namespace for message)"/>
   </input>
   </operation>

  • The WSDL extract shows an RPC operation named schedulePayment being invoked in RPC/encoded format, with SOAP encodings and two input parameters.

  • SOAP message

   <soapenv:body xmlns:mns="(namespace for message)">
   <mns:schedulePayment>
        <part1 HREF="#1" TARGET="_self"/>
        <part2>5688</part2>
   </mns:schedulePayment>

   <mns:PaymentDetails id="#1">
        <balance>8933</balance>
        <payeeName>johnmalkovich</payeeName>
   </mns:PaymentDetails>
   </soapenv:body>

Style

RPC/literal

   <operation name="schedulePayment"
              style="rpc" ... >
     <input>
         <soap:body use="literal"
                 parts="part1 part2 part3 part4"
    namespace="(namespace for message)"/>
     </input>
   // ...
   </operation>

  • The WSDL extract shows an RPC operation named schedulePayment being invoked in RPC/literal format, with four input parameters. It shows how data types can be passed and how a schema element is sent across the wire directly, without any encoding.

  • SOAP message

   <soapenv:body xmlns:mns="(namespace for message)"
           xmlns:typens="(namespace for service schema)".. >
   <mns:schedulePayment>

   <mns:part1>

   <typens:balance>8933</typens:balance>
       <typens:payeeName>johnmalkovich
                    </typens:payeeName>
   </mns:part1>

   <mns:part2>5688</mns:part2>

   <mns:part3>

   <typens:Amount>5688</typens:Amount>
   </mns:part3>

   <mns:part4>
         <typens:PaymentDetail>
         <typens:balance>8933</typens:balance>
         <typens:payeeName>johnmalkovich
                        </typens:payeeName>
   </typens:PaymentDetail>
   </mns:part4>

   </mns:schedulePayment>
   </soapenv:body>

Style

Document/literal

   <operation name="schedulePayment"
                  style="document" ... >
   <input>
   <soap:body parts="part1 part3 part4"
              use="literal">
   </input>
   </operation>

  • The WSDL extract shows a document-style message being sent in literal format with four input parameters. It shows how data types can be passed and how a schema element is sent across the wire directly, without any encoding.

  • SOAP message

   <soapenv:body
               xmlns:typens="(namespace for service schema)" ... >

   <typens:balance>8933</typens:balance>
   <typens:payeeName>johnmalkovich
                 </typens:payeeName>

   <typens:Amount>5688</typens:Amount>

   <typens:details>
      <typens:balance>5688</typens:balance>
      <typens:payeeName>johnmalkovich

   </typens:payeeName>
   </typens:details>
   </soapenv:body>

Style

Document/encoded

   <operation name="schedulePayment"
              style="document" ... >
   <input>
   <soap:body parts="part1 part2"
              use="encoded"
              encoding=
   "http://schemas.xmlsoap.org/soap/encoding/"
      namespace="(namespace for message)"/>
   </input>
   </operation>

  • The WSDL extract shows a document style message being sent with SOAP encoding and four input parameters. It shows how data types can be passed and how a schema element is sent across the wire directly.

  • SOAP message

   <soapenv:body ...
                xmlns:mns="(namespace for message)">
   <mns:PaymentDetails>
       <balance>8933</balance>
       <payeeName>johnmalkovich</payeeName>
   </mns:PaymentDetails>

   <soapenc:int>5688</soapenc:int>
   </soapenv:body>

<definitions
  targetNamespace="(namespace for service WSDL)"
  xml:typens="(namespace for service schema)">

<types>
<schema targetNamespace="(namespace for the schema)">
  <element name="Amount" type="xsd:int"/>
  <element name="details" type="typens:PaymentDetail"/>
<!--user defined data type-->
  <complexType name="PaymentDetail">
     <sequence>
         <element name="balance" type="xsd:int"/>
         <element name="payeeName" type="xsd:string"/>
     </sequence>
  </complexType>
</schema>
</types>

<message...>
  <part name='part1' type="typens: PaymentDetail"/>
  <part name='part2' type="xsd:int"/>
  <part name='part3' element="typens:Amount"/>
  <part name='part4' element="typens:details"/>
</message>
...
</definitions>

When to Use RPC/Encoded and Document/Literal

To best choose a particular style, an architect would need to understand the implementation or desired use. In general, however, the effort and complexity involved in document style service is greater than for RPC style—for example, in negotiating the schema design with the business partners and validating the document against the schema. When architecting applications, these are some of the decision points for deciding between RPC or document style:

  1. State maintenance. If multiple service invocations are involved in a single business transaction, with state maintained between the service invocations, the service must maintain state. Maintaining state is nontrivial and is usually not as simple as exposing a stateful EJB as a Web service over multiple RPC invocations. One alternative is to use document style, pass the contents of an entire transaction in the document, and allow the service implementation to ensure the sequence and state maintenance in the transaction. Information about that state can be returned in a token or in the resulting document to the client if needed.

    If the service consumer is only requesting information or persisting information in a specific format (e.g., industry-standard XML schema), a document style message makes more sense, because it is not constrained by the RPC-oriented encoding.

  2. Integration with external parties and decoupled interfaces. Service consumers outside the enterprise typically have little control over the use and consequences of changes to the service interface. RPC interfaces are expected not to change, because any change would break the contract between the service and its consumers. In scenarios where a large number of applications have produced stub code from the service's WSDL document (we will see how to do this later in this chapter), changing the WSDL would cause all the applications that rely on a specific method signature to break. If you anticipate frequent changes, you can use a document/literal style, because the impact on the WSDL can be minimized. This is useful for the late binding pattern discussed in Chapter 5.

  3. Validate business documents. A Web service can use the capabilities of a validating parser and schemas to describe and validate high-level business documents. This is opposed to RPC, where the XML describes the method and parameters encoded for that method call, which cannot be used to enforce high-level business rules.

    To enforce these rules for the document with RPC, a message must include an XML document as a string parameter or attachment and must hide the validation in the implementation of the method being called. If an attachment is not used, the service will have to deal with custom marshalling and unmarshalling code for a possibly complex XML structure. This often leads to valid calls with invalid parameters that are not detected till the entire structure has been processed. In short, if the service is accepting or returning a complex XML structure, a document style is better suited. The XML can be validated against the schema prior to calling the service, and no custom marshalling code is required.

  4. Performance and memory limitations. Marshalling and unmarsalling parameters to XML in memory can be an intensive process. The SOAP model inherently requires DOM-based processing of the envelope, which can lead to large DOM trees in memory if the XML representation is complex. However, document style services can choose SAX handling of the including XML document, to perform quicker and less memory intensive parsing. This is critical for services that handle many simultaneous requests.

  5. For fine-grained communication. With RPC calls, only a limited amount of data can be passed around in a single invocation, and it is not possible to include multiple RPC calls in a single SOAP envelope. If the application requires a significant amount of data to be passed around, RPC style with an attachment (e.g.. an XML document) is better suited.

  6. Request-response processing. SOAP messages are, by nature, one-way transmissions from a sender to a receiver, but they are usually combined to implement a request/response model. SOAP piggybacking on top of a request-response-oriented transport, such as HTTP and JAX-RPC, is well suited to applications that require synchronous request-response processing. Such applications typically involve retrieval of results based on some remote procedure execution, for which RPC/encoded messages are well suited.

  7. Encoding scheme. The default encoding scheme specified by SOAP is usually sufficient. If you determine a need to use custom encoding (e.g., the SOAP encoding doesn't meet your needs because you have complex types not addressed by JAX-RPC and SOAP), we recommend that you investigate the document style route instead, since schemas are by far a richer metalanguage than SOAP encoding. This allows for a more complex arrangement of information.

Document style combined with literal encoding allows validation. Changing that to RPC/literal takes that benefit away, because the surrounding RPC element does not appear in the schemas. A possible example where RPC/literal can be used instead of document/literal is when multiple RPC operations return XML documents using the same schema. Document/encoded takes away the benefits of RPC/encoded but does not add anything in return.


Previous Section Next Section


JavaScript Editor Java Tutorials Free JavaScript Editor