| <html> |
| <head> |
| <meta http-equiv="content-type" content=""> |
| <title>JiBX unwrapped document/literal</title> |
| <link href="../../css/axis-docs.css" rel="stylesheet" type="text/css" media="all" /> |
| </head> |
| |
| <body> |
| <h1>JiBX Unwrapped document/literal</h1> |
| |
| <p>Code generation for JiBX data binding converts operations defined by a Web |
| service to method calls. In the most general case of document/literal |
| (doc/lit) Web services the generated methods each take a single parameter |
| object and return a single result object. This type of interface can be |
| painful for developers because it adds both a layer of indirection and |
| potentially a large number of extra classes (one input and one output class |
| for each generated method).</p> |
| |
| <p>Fortunately, there's an alternative way of generating methods that gives a |
| much more usable API for many Web services. This alternative is called |
| <i>unwrapping</i>, and the service definitions that it applies to are called |
| <i>wrapped</i> definitions. The key difference that qualifies a service |
| definition as wrapped is the structure of the input and output elements used |
| for operations.</p> |
| |
| <p>Here's a sample wrapped WSDL (partial) by way of an example:</p> |
| <pre><wsdl:definitions targetNamespace="http://ws.sosnoski.com/library/wsdl" |
| xmlns:tns="http://ws.sosnoski.com/library/types" |
| xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" |
| xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"> |
| |
| <wsdl:types> |
| |
| <schema elementFormDefault="qualified" |
| targetNamespace="http://ws.sosnoski.com/library/types" |
| xmlns="http://www.w3.org/2001/XMLSchema"> |
| |
| <element name="getBook"> |
| <complexType> |
| <sequence> |
| <element name="isbn" type="string"/> |
| </sequence> |
| </complexType> |
| </element> |
| |
| <element name="getBookResponse"> |
| <complexType> |
| <sequence> |
| <element name="book" minOccurs="0" type="tns:BookInformation"/> |
| </sequence> |
| </complexType> |
| </element> |
| |
| <element name="addBook"> |
| <complexType> |
| <sequence> |
| <element name="type" type="string"/> |
| <element name="isbn" type="string"/> |
| <element name="author" minOccurs="0" maxOccurs="unbounded" type="string"/> |
| <element name="title" type="string"/> |
| </sequence> |
| </complexType> |
| </element> |
| |
| <element name="addBookResponse"> |
| <complexType> |
| <sequence> |
| <element name="success" type="boolean"/> |
| </sequence> |
| </complexType> |
| </element> |
| |
| <complexType name="BookInformation"> |
| <sequence> |
| <element name="author" minOccurs="0" maxOccurs="unbounded" type="string"/> |
| <element name="title" type="string"/> |
| </sequence> |
| <attribute name="type" use="required" type="string"/> |
| <attribute name="isbn" use="required" type="string"/> |
| </complexType> |
| |
| </schema> |
| |
| </wsdl:types> |
| |
| <wsdl:message name="getBookRequest"> |
| <wsdl:part element="wns:getBook" name="parameters"/> |
| </wsdl:message> |
| |
| <wsdl:message name="getBookResponse"> |
| <wsdl:part element="wns:getBookResponse" name="parameters"/> |
| </wsdl:message> |
| |
| <wsdl:message name="addBookRequest"> |
| <wsdl:part element="wns:addBook" name="parameters"/> |
| </wsdl:message> |
| |
| <wsdl:message name="addBookResponse"> |
| <wsdl:part element="wns:addBookResponse" name="parameters"/> |
| </wsdl:message> |
| |
| <wsdl:portType name="Library"> |
| |
| <wsdl:operation name="getBook"> |
| <wsdl:input message="wns:getBookRequest" name="getBookRequest"/> |
| <wsdl:output message="wns:getBookResponse" name="getBookResponse"/> |
| </wsdl:operation> |
| |
| <wsdl:operation name="addBook"> |
| <wsdl:input message="wns:addBookRequest" name="addBookRequest"/> |
| <wsdl:output message="wns:addBookResponse" name="addBookResponse"/> |
| </wsdl:operation> |
| |
| </wsdl:portType> |
| ... |
| </wsdl:definitions></pre> |
| |
| <p>This WSDL defines a service with just two operations: <b>getBook</b> and |
| <b>addBook</b>. The <b>getBook</b> operation takes a <i>getBook</i> element |
| as input, and returns a <i>getBookResponse</i> element as output, while |
| <b>addBook</b> takes an <i>addBook</i> element as input and returns an |
| <i>addBookResponse</i> as output. Each of these input and output elements in |
| turn consists of a sequence of child elements, with some of the child |
| elements defined directly using standard schema types and others referencing |
| user-defined schema types.</p> |
| |
| <p>As I said up front, this WSDL qualifies for unwrapped handling using JiBX. |
| Here's the body of the client interface generated when using unwrapping (the |
| <i>-uw</i> option for WSDL2Java):</p> |
| <pre> public interface LibraryJibxUnwrapped { |
| |
| |
| /** |
| * Auto generated method signatures |
| * @param type* @param isbn* @param author* @param title |
| */ |
| public boolean addBook( |
| java.lang.String type,java.lang.String isbn,java.lang.String[] author,java.lang.String title) throws java.rmi.RemoteException |
| |
| |
| ; |
| |
| |
| /** |
| * Auto generated method signatures |
| * @param isbn |
| */ |
| public com.sosnoski.ws.library.jibx.beans.Book getBook( |
| java.lang.String isbn) throws java.rmi.RemoteException |
| |
| |
| ; |
| |
| |
| |
| // |
| }</pre> |
| |
| <p>You can see that the JiBX code generation converted the operations into |
| simple method call interfaces without introducing any extraneous objects (see |
| <a href="./jibx-doclit-example.html">JiBX Document/Literal Example</a> for |
| the interface generated when unwrapping is not used). The server-side |
| interface is the same.</p> |
| |
| <p>The key points that allow unwrapped handling with JiBX are:</p> |
| <ol> |
| <li>Each operation either accepts no input, or the input consists of a |
| single element.</li> |
| <li>Each input element is defined as a schema <i>complexType</i> consisting |
| of a <i>sequence</i> of any number of child elements.</li> |
| <li>Each operation either generates no output, or the output consists of a |
| single element.</li> |
| <li>Each output element is defined as a schema <i>complexType</i> |
| consisting of a <i>sequence</i> that's either empty or contains a single |
| child element.</li> |
| <li>The child elements of both inputs and outputs are defined using |
| <i>type</i> references, rather than an embedded type definitions.</li> |
| </ol> |
| |
| <p>You also need to supply an appropriate JiBX binding definition (using the |
| <i>-Ebindingfile {file}</i> parameter for WSDL2Java - see <a |
| href="./jibx-codegen-integration.html#codegen">JiBX Codegen Integration - |
| WSDL2Java usage</a> for more details). This must define abstract |
| <i>mapping</i>s for the <i>complexType</i>s referenced by child elements of |
| the inputs and outputs, with a <i>type-name</i> attribute matching the schema |
| <i>complexType</i> name. If the child elements reference schema |
| <i>simpleType</i> definitions the binding must also define a <i>format</i>s |
| for each <i>simpleType</i>, with a <i>label</i> attribute matching the schema |
| <i>simpleType</i> name. The binding definition must also specify the |
| <i>force-classes='true'</i> attribute on the <i>binding</i> element.</p> |
| |
| <p>For example, here's a binding definition that matches the above WSDL:</p> |
| <pre><binding force-classes="true" xmlns:tns="http://ws.sosnoski.com/library/types"> |
| |
| <namespace uri="http://ws.sosnoski.com/library/types" default="elements"/> |
| |
| <mapping abstract="true" class="com.sosnoski.ws.library.jibx.beans.Book" |
| type-name="tns:BookInformation"> |
| <value name="type" style="attribute" field="m_type"/> |
| <value name="isbn" style="attribute" field="m_isbn"/> |
| <collection field="m_authors"> |
| <value name="author"/> |
| </collection> |
| <value name="title" field="m_title"/> |
| </mapping> |
| |
| </binding></pre> |
| |
| <p>And here's the actual <code>com.sosnoski.ws.library.jibx.beans.Book</code> |
| class:</p> |
| <pre>package com.sosnoski.ws.library.jibx.beans; |
| |
| public class Book |
| { |
| private String m_type; |
| private String m_isbn; |
| private String m_title; |
| private String[] m_authors; |
| |
| public Book() {} |
| |
| public String getType() { |
| return m_type; |
| } |
| |
| public String getIsbn() { |
| return m_isbn; |
| } |
| |
| public String getTitle() { |
| return m_title; |
| } |
| |
| public String[] getAuthors() { |
| return m_authors; |
| } |
| }</pre> |
| |
| <p>The JiBX code generation for Axis2 currently requires that classes |
| coresponding to unwrapped child elements (such as |
| <code>com.sosnoski.ws.library.jibx.beans.Book</code>, in this case) provide |
| public default (no-argument) constructors.</p> |
| |
| <p>JiBX handling allows the child elements of both inputs and outputs to be |
| optional (with <i>nillable='true'</i>, <i>minOccurs='0'</i>, or both), |
| providing the binding converts these child elements to object types rather |
| than primitive types. It also allows repeated child elements (with |
| <i>minOccurs='unbounded'</i>, or any value of <i>minOccurs</i> greater than |
| one), representing the repeated elements as arrays of the corresponding |
| object or primitive types.</p> |
| </body> |
| </html> |