Chapter

156
Chapter 1. XML Web Service Standards Given XML documents, schemas, and fragments determine whether their syntax and form are correct (according to W3C schema) and whether they conform to the WS-I Basic Profile 1.1. Basic Profile. SOAP Envelopes An ENVELOPE MUST conform to the structure specified in SOAP 1.1 Section 4, "SOAP Envelope" An ENVELOPE MUST have exactly zero or one child elements of the soap:Body element. A RECEIVER MUST generate a fault if they encounter an envelope whose document element is not soap:Envelope. The children of the soap:Body element in an ENVELOPE MUST be namespace qualified. An ENVELOPE MUST NOT contain a Document Type Declaration. An ENVELOPE MUST NOT contain Processing Instructions. An ENVELOPE SHOULD NOT contain the namespace declaration xmlns:xml="http://www.w3.org/XML/1998/namespace". A DESCRIPTION SHOULD NOT contain the namespace declaration xmlns:xml="http://www.w3.org/XML/1998/namespace". An ENVELOPE MUST NOT have any element children of soap:Envelope following the soap:Body element. CORRECT example: <soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' > <soap:Body> <p:Process xmlns:p='http://example.org/Operations' > <m:Data xmlns:m='http://example.org/information' > Here is some data with the message </m:Data> </p:Process> </soap:Body> </soap:Envelope> INCORRECT example: <soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' > <soap:Body> <p:Process xmlns:p='http://example.org/Operations' /> </soap:Body> <m:Data xmlns:m='http://example.org/information' > Here is some data with the message </m:Data> </soap:Envelope> An ENVELOPE MUST NOT contain soap:encodingStyle attributes on any of the elements whose namespace name is"http://schemas.xmlsoap.org/soap/envelope/". An ENVELOPE MUST NOT contain soap:encodingStyle attributes on any element that is a child of soap:Body. An ENVELOPE described in an rpc-literal binding MUST NOT contain soap:encodingStyle attribute on any element that is a grandchild of soap:Body.

Transcript of Chapter

Page 1: Chapter

Chapter 1. XML Web Service Standards

Given XML documents, schemas, and fragments determine whether their syntax and form are correct (according to W3C schema) and whether they conform to the WS-I Basic Profile 1.1.

Basic Profile. SOAP Envelopes

An ENVELOPE MUST conform to the structure specified in SOAP 1.1 Section 4, "SOAP Envelope"

An ENVELOPE MUST have exactly zero or one child elements of the soap:Body element.

A RECEIVER MUST generate a fault if they encounter an envelope whose document element is not soap:Envelope.

The children of the soap:Body element in an ENVELOPE MUST be namespace qualified.

An ENVELOPE MUST NOT contain a Document Type Declaration.

An ENVELOPE MUST NOT contain Processing Instructions.

An ENVELOPE SHOULD NOT contain the namespace

declaration xmlns:xml="http://www.w3.org/XML/1998/namespace".

A DESCRIPTION SHOULD NOT contain the namespace

declaration xmlns:xml="http://www.w3.org/XML/1998/namespace".

An ENVELOPE MUST NOT have any element children of soap:Envelope following the soap:Body element.

CORRECT example:

<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' > <soap:Body> <p:Process xmlns:p='http://example.org/Operations' > <m:Data xmlns:m='http://example.org/information' > Here is some data with the message </m:Data> </p:Process> </soap:Body> </soap:Envelope>

INCORRECT example:

<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' > <soap:Body> <p:Process xmlns:p='http://example.org/Operations' /> </soap:Body> <m:Data xmlns:m='http://example.org/information' > Here is some data with the message </m:Data> </soap:Envelope>

An ENVELOPE MUST NOT contain soap:encodingStyle attributes on any of the elements whose namespace name

is"http://schemas.xmlsoap.org/soap/envelope/".

An ENVELOPE MUST NOT contain soap:encodingStyle attributes on any element that is a child of soap:Body.

An ENVELOPE described in an rpc-literal binding MUST NOT contain soap:encodingStyle attribute on any element that is a

grandchild of soap:Body.

Page 2: Chapter

An ENVELOPE containing a soap:mustUnderstand attribute MUST only use the lexical forms "0" and "1".

A RECEIVER MUST NOT mandate the use of the xsi:type attribute in envelopes except as required in order to indicate a derived type (see XML Schema Part 1: Structures, Section 2.6.1).

The soap:Envelope, soap:Header, and soap:Body elements in an ENVELOPE MUST NOT have attributes in the

namespace"http://schemas.xmlsoap.org/soap/envelope/".

Basic Profile. SOAP Processing Model

A RECEIVER MUST handle envelopes in such a way that it appears that all checking of mandatory header blocks is performed before any actual processing.

A RECEIVER MUST generate a "soap:MustUnderstand" fault when an envelope contains a mandatory header block (i.e., one

that has a soap:mustUnderstandattribute with the value "1") targeted at the receiver (via soap:actor) that the receiver does not understand.

When a fault is generated by a RECEIVER, further processing SHOULD NOT be performed on the SOAP envelope aside from that which is necessary to rollback, or compensate for, any effects of processing the envelope prior to the generation of the fault.

Where the normal outcome of processing a SOAP envelope would have resulted in the transmission of a SOAP response, but rather a fault is generated instead, a RECEIVER MUST transmit a fault in place of the response.

A RECEIVER that generates a fault SHOULD notify the end user that a fault has been generated when practical, by whatever means is deemed appropriate to the circumstance.

Basic Profile. SOAP Faults

A RECEIVER MUST interpret a SOAP message as a Fault when the soap:Body of the message has a single soap:Fault child.

When an ENVELOPE is a Fault, the soap:Fault element MUST NOT have element children other

than faultcode, faultstring, faultactor and detail.

CORRECT example:

<soap:Fault xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' > <faultcode>soap:Client</faultcode> <faultstring>Invalid message format</faultstring> <faultactor>http://example.org/someactor</faultactor> <detail> <m:msg xmlns:m='http://example.org/faults/exceptions'> There were <b>lots</b> of elements in the message that I did not understand </m:msg> <m:Exception xmlns:m='http://example.org/faults/exceptions'> <m:ExceptionType>Severe</m:ExceptionType> </m:Exception> </detail> </soap:Fault>

INCORRECT example:

<soap:Fault xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' > <faultcode>soap:Client</faultcode> <faultstring>Invalid message format</faultstring> <faultactor>http://example.org/someactor</faultactor> <detail> There were <b>lots</b> of elements in the message that I did not understand </detail> <m:Exception xmlns:m='http://example.org/faults/exceptions' > <m:ExceptionType>Severe</m:ExceptionType> </m:Exception> </soap:Fault>

Page 3: Chapter

When an ENVELOPE is a Fault, the element children of the soap:Fault element MUST be unqualified.

CORRECT example:

<soap:Fault xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' xmlns='' > <faultcode>soap:Client</faultcode> <faultstring>Invalid message format</faultstring> <faultactor>http://example.org/someactor</faultactor> <detail> <m:msg xmlns:m='http://example.org/faults/exceptions'> There were <b>lots</b> of elements in the message that I did not understand </m:msg> </detail> </soap:Fault>

INCORRECT example (children of the soap:Fault elements have namespace qualification):

<soap:Fault xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' > <soap:faultcode>soap:Client</soap:faultcode> <soap:faultstring>Invalid message format</soap:faultstring> <soap:faultactor>http://example.org/someactor</soap:faultactor> <soap:detail> <m:msg xmlns:m='http://example.org/faults/exceptions'> There were <b>lots</b> of elements in the message that I did not understand </m:msg> </soap:detail> </soap:Fault>

A RECEIVER MUST accept faults that have any number of elements, including zero, appearing as children of the detail element. Such children can be qualified OR unqualified.

A RECEIVER MUST accept faults that have any number of qualified OR unqualified attributes, including zero, appearing on the detail element. The namespace of qualified attributes can be anything other than "http://schemas.xmlsoap.org/soap/envelope/".

A RECEIVER MUST accept faults that carry an xml:lang attribute on the faultstring element.

When an ENVELOPE contains a faultcode element, the content of that element SHOULD be either one of the fault codes defined in

SOAP 1.1 (supplying additional information if necessary in the detail element), or a Qname whose namespace is controlled by the fault's specifying authority (in that order of preference).

NOTE: The set of faultcode values defined in SOAP 1.1 document

is: VersionMismatch, MustUnderstand, Client, Server.

When an ENVELOPE contains a faultcode element the content of that element SHOULD NOT use of the SOAP 1.1 "dot" notation to refine the meaning of the fault.

CORRECT example:

<soap:Fault xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' xmlns:c='http://example.org/faultcodes' > <faultcode>c:ProcessingError</faultcode> <faultstring>An error occured while processing the message</faultstring> </soap:Fault>

Page 4: Chapter

CORRECT example:

<soap:Fault xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' > <faultcode>soap:Server</faultcode> <faultstring>An error occured while processing the message</faultstring> </soap:Fault>

INCORRECT example:

<soap:Fault xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' xmlns:c='http://example.org/faultcodes' > <faultcode>soap:Server.ProcessingError</faultcode> <faultstring>An error occurred while processing the message</faultstring> </soap:Fault>

Basic Profile. Use of SOAP in HTTP

A MESSAGE MUST be sent using either HTTP/1.1 or HTTP/1.0.

A MESSAGE SHOULD be sent using HTTP/1.1.

A HTTP request MESSAGE MUST use the HTTP POST method.

A MESSAGE MUST NOT use the HTTP Extension Framework (RFC2774).

The value of the SOAPAction HTTP header field in a HTTP request MESSAGE MUST be a quoted string.

A RECEIVER MAY respond with a fault if the value of the SOAPAction HTTP header field in a message is not quoted.

A RECEIVER MUST NOT rely on the value of the SOAPAction HTTP header to correctly process the message.

CORRECT example #1:

A WSDL Description that has:

<soapbind:operation soapAction="foo" />

results in a message with a SOAPAction HTTP header field of:

SOAPAction: "foo"

CORRECT example #2:

A WSDL Description that has:

<soapbind:operation />

or

<soapbind:operation soapAction="" />

results in a message with a corresponding SOAPAction HTTP header field as follows:

SOAPAction: ""

Page 5: Chapter

An INSTANCE MUST use a 2xx HTTP status code on a response message that indicates the successful outcome of a HTTP request.

An INSTANCE SHOULD use a "200 OK" HTTP status code on a response message that contains an envelope that is not a fault.

Basic Profile. Service Description. Document Structure

A DESCRIPTION MUST only use the WSDL "import" statement to import another WSDL description.

In a DESCRIPTION, the namespace attribute of the wsdl:import MUST NOT be a relative URI.

To import XML Schema Definitions, a DESCRIPTION MUST use the XML Schema "import" statement.

A DESCRIPTION MUST use the XML Schema "import" statement only within the xsd:schema element of the types section.

In a DESCRIPTION the schemaLocation attribute of an xsd:import element MUST NOT resolve to any document whose

root element is not "schema" from the namespace "http://www.w3.org/2001/XMLSchema".

CORRECT description example:

<definitions name="StockQuote" targetNamespace="http://example.com/stockquote/definitions" ... xmlns="http://schemas.xmlsoap.org/wsdl/"> <import namespace="http://example.com/stockquote/definitions" location="http://example.com/stockquote/stockquote.wsdl"/> <message name="GetLastTradePriceInput"> <part name="body" element="..."/> </message> ... </definitions>

CORRECT description example:

<definitions name="StockQuote" targetNamespace="http://example.com/stockquote/" xmlns:xsd1="http://example.com/stockquote/schemas" ... xmlns="http://schemas.xmlsoap.org/wsdl/"> <import namespace="http://example.com/stockquote/definitions" location="http://example.com/stockquote/stockquote.wsdl"/> <message name="GetLastTradePriceInput"> <part name="body" element="xsd1:TradePriceRequest"/> </message> ... </definitions>

INCORRECT description example (imports not "wsdl" document):

<definitions name="StockQuote" targetNamespace="http://example.com/stockquote/definitions" xmlns:xsd1="http://example.com/stockquote/schemas" ... xmlns="http://schemas.xmlsoap.org/wsdl/"> <import namespace="http://example.com/stockquote/schemas"

Page 6: Chapter

location="http://example.com/stockquote/stockquote.xsd"/> <message name="GetLastTradePriceInput"> <part name="body" element="xsd1:TradePriceRequest"/> </message> ... </definitions>

A DESCRIPTION MUST specify a non-empty location attribute on the wsdl:import element.

When they appear in a DESCRIPTION, wsdl:import elements MUST precede all other elements from the WSDL namespace

except wsdl:documentation.

When they appear in a DESCRIPTION, wsdl:types elements MUST precede all other elements from the WSDL namespace

except wsdl:documentation andwsdl:import.

CORRECT example:

<definitions name="StockQuote" targetNamespace="http://example.com/stockquote/definitions"> <import namespace="http://example.com/stockquote/base" location="http://example.com/stockquote/stockquote.wsdl"/> <message name="GetLastTradePriceInput"> <part name="body" element="..."/> </message> ... </definitions>

CORRECT example:

<definitions name="StockQuote" ... xmlns="http://schemas.xmlsoap.org/wsdl/"> <types> <schema targetNamespace="http://example.com/stockquote/schemas" xmlns="http://www.w3.org/2001/XMLSchema"> ....... </schema> </types> <message name="GetLastTradePriceInput"> <part name="body" element="tns:TradePriceRequest"/> </message> ... <service name="StockQuoteService"> <port name="StockQuotePort" binding="tns:StockQuoteSoap"> .... </port> </service> </definitions>

INCORRECT example (wsdl:types elements MUST precede all other elements):

<definitions name="StockQuote" ... xmlns="http://schemas.xmlsoap.org/wsdl/"> <import namespace="http://example.com/stockquote/definitions" location="http://example.com/stockquote/stockquote.wsdl"/> <message name="GetLastTradePriceInput"> <part name="body" type="tns:TradePriceRequest"/>

Page 7: Chapter

</message> ... <service name="StockQuoteService"> <port name="StockQuotePort" binding="tns:StockQuoteSoap"> .... </port> </service> <types> <schema targetNamespace="http://example.com/stockquote/schemas" xmlns="http://www.w3.org/2001/XMLSchema"> ....... </schema> </types> </definitions>

Basic Profile. Service Description. Types

A DESCRIPTION MUST NOT use QName references to WSDL components in namespaces that have been neither imported, nor defined in the referring WSDL document.

A QName reference to a Schema component in a DESCRIPTION MUST use the namespace defined in

the targetNamespace attribute on the xsd:schemaelement, or to a namespace defined in the namespace attribute

on an xsd:import element within the xsd:schema element.

In a DESCRIPTION, declarations MUST NOT extend or restrict the soapenc:Array type.

In a DESCRIPTION, declarations MUST NOT use wsdl:arrayType attribute in the type declaration.

In a DESCRIPTION, elements SHOULD NOT be named using the convention ArrayOfXXX.

An ENVELOPE MUST NOT include the soapenc:arrayType attribute.

CORRECT example:

Given the WSDL Description:

<xsd:element name="MyArray1" type="tns:MyArray1Type"/> <xsd:complexType name="MyArray1Type"> <xsd:sequence> <xsd:element name="x" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType>

The envelope would serialize as (omitting namespace declarations for clarity):

<MyArray1> <x>abcd</x> <x>efgh</x> </MyArray1>

INCORRECT example:

Given the WSDL Description:

<xsd:element name="MyArray2" type="tns:MyArray2Type"/> <xsd:complexType name="MyArray2Type" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" > <xsd:complexContent> <xsd:restriction base="soapenc:Array"> <xsd:sequence>

Page 8: Chapter

<xsd:element name="x" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> <xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="tns:MyArray2Type[]"/> </xsd:restriction> </xsd:complexContent> </xsd:complexType>

The envelope would serialize as (omitting namespace declarations for clarity):

<MyArray2 soapenc:arrayType="tns:MyArray2Type[]" > <x>abcd</x> <x>efgh</x> </MyArray2>

Describe the use of XML schema in Java EE Web services.

• [SCHEMA_PART_0] XML Schema Part 0: Primer Second Edition

• [SOAP_1.2_PART_2] SOAP Version 1.2 Part 2: Adjuncts

The W3C XML Schema Definition Language is a way of describing and constraining the content of XML documents.

The XML Schema specification consists of three parts. One part defines a set of simple datatypes, which can be associated with XML element types and attributes; this allows XML software to do a better job of managing dates, numbers, and other special forms of information. The second part of the specification proposes methods for describing the structure and constraining the contents of XML documents, and defines the rules governing schema validation of documents. The third part is a primer that explains what schemas are, how they differ from DTDs, and how one builds a schema.

XML Schema introduces new levels of flexibility that may accelerate the adoption of XML for significant industrial use. For example, a schema author can build a schema that borrows from a previous schema, but overrides it where new unique features are needed. XML Schema allows the author to determine which parts of a document may be validated, or identify parts of a document where a schema may apply. XML Schema also provides a way for users of e-commerce systems to choose which XML Schema they use to validate elements in a given namespace, thus providing better assurance in e-commerce transactions and greater security against unauthorized changes to validation rules. Further, as XML Schema are XML documents themselves, they may be managed by XML authoring tools, or through XSLT.

Let's start from "Hello World!" example:

<?xml version="1.0" encoding="UTF-8" ?> <greeting> Hello World! </greeting> <?xml version="1.0" encoding="UTF-8" ?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="greeting" type="xsd:string"/> </xsd:schema>

Here is a simple data structure for a purchase order. The order example contains following elements: company name, product identifier, and price.

<?xml version="1.0" encoding="UTF-8" ?> <order_request> <company_name>IBA JV</company_name> <product_id>C-0YST</product_id> <product_price>500.00</product_price> </order_request>

Page 9: Chapter

This example represents pricing data as a floating-point number and company name and product identifier as strings. Agreement among different programs about how to handle data is essential. XML solves data typing issues through the use of XML Schemas. The following example shows how each element in the order request can be designated a specific data type:

<?xml version="1.0" encoding="UTF-8" ?> <xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'> <xsd:element name="order_request"> <xsd:complexType> <xsd:sequence> <xsd:element name="company_name" type="xsd:string"/> <xsd:element name="product_id" type="xsd:string"/> <xsd:element name="product_price" type="xsd:double"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema>

Another example of XML document for more complex purchase order:

<?xml version="1.0" encoding="UTF-8" ?> <purchase_order order_date="2004-04-07"> <shipping_address country="US"> <name>Mikalai Zaikin</name> <street>28th Street</street> <city>Boulder</city> <state>CO</state> <zip>80301</zip> </shipping_address> <items> <item part_number="008291"> <product_name>PRESARIO S5140</product_name> <quantity>1</quantity> <price>898.00</price> </item> <item part_number="005376"> <product_name>COMPAQ FP7317</product_name> <quantity>1</quantity> <price>398.00</price> </item> </items> </purchase_order>

The XML Schema (one of many possible) for this document will be:

<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="item"> <xsd:complexType> <xsd:sequence> <xsd:element name="product_name" type="xsd:string" /> <xsd:element name="quantity"> <xsd:simpleType> <xsd:restriction base="xsd:positiveInteger"> <xsd:maxExclusive value="100"/> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="price" type="xsd:decimal" /> </xsd:sequence> <xsd:attribute name="part_number" type="xsd:string" use="required" /> </xsd:complexType> </xsd:element> <xsd:element name="items"> <xsd:complexType> <xsd:sequence> <xsd:element maxOccurs="unbounded" minOccurs="1" ref="item" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="purchase_order">

Page 10: Chapter

<xsd:complexType> <xsd:sequence> <xsd:element name="shipping_address" type="us_address" /> <xsd:element ref="items" /> </xsd:sequence> <xsd:attribute name="order_date" type="xsd:date" use="required" /> </xsd:complexType> </xsd:element> <xsd:complexType name="us_address"> <xsd:sequence> <xsd:element name="name" type="xsd:string" /> <xsd:element name="street" type="xsd:string" /> <xsd:element name="city" type="xsd:string" /> <xsd:element name="state" type="xsd:string" /> <xsd:element name="zip" type="xsd:string" /> </xsd:sequence> <xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US" /> </xsd:complexType> </xsd:schema>

NOTE: In SOAP 1.2 multireference values may be encoded in-place rather than as "top-level" elements (as in SOAP 1.1):

SOAP 1.1

<e:Books> <e:Book> <title>SCDJWS 1.4 Study Guide</title> <author href="#mz" /> </e:Book> <e:Book> <title>SCWCD 1.4 Study Guide</title> <author href="#mz" /> </e:Book> </e:Books> <author id="henryford"> <name>Mikalai Zaikin</name> </author>

SOAP 1.2

<e:Books> <e:Book> <title>SCDJWS 5.0 Study Guide</title> <author id="mz" > <name>Mikalai Zaikin</name> </author> </e:Book> <e:Book> <title>SCWCD 5.0 Study Guide</title> <author ref="mz" /> </e:Book> </e:Books>

The following code:

public class PersonName { public String firstName; public String lastName; } public class Person { public PersonName name; public float age; public short height; public static boolean compare(Person person1, Person person2); }

The SOAP 1.2 message for Person.compare(...) call may look like this:

Page 11: Chapter

<soap:Envelope xmlns:soap='http://www.w3.org/2002/12/soap-envelope' soap:encodingStyle='http://www.w3.org/2002/12/soap-encoding'> <soap:Body xmlns:ns1='http://example'> <ns1:compare> <person id="mz"> <name> <fistName>Mikalai</firstName> <lastName>Zaikin</lastName> </name> <age>29</age> <height>1.78</height> <person> <person ref="mz" /> </ns1:compare> </soap:Body> </soap:Envelope>

Default value of minOccurs is 1.

Default value of maxOccurs is 1.

XML Schema defines four main elements:

1. xsd:element declares an element and assigns it a type.

2. xsd:attribute declares an attribute and assigns it a type.

3. xsd:complexType defines a new complex type.

4. xsd:simpleType defines a new simple type.

Attribute values are always simple types. Attributes are unordered.

It does not matter whether complex type is defined before or after the element declaration as long as it is present in the schema document.

You can derive new simple types from existing types. An xsd:simpleType element defines the subtype. The name attribute

of xsd:simpleType assigns a name to the new type, by which it can be referred to in xsd:element type attributes.

An xsd:restriction child element derives by restricting the legal values of the base type. An xsd:list child element

derives a type as a white space separated list of base type instances. An xsd:union child element derives by combining legal values from multiple base types.

You can derive new simple types types from existing types by restricting the type to a subset of its normal values.

An xsd:simpleType element defines the restricted type. The name attribute of xsd:simpleType assigns a name to

the new type. An xsd:restriction child element specifies what type is being restricted via its base attribute. Facet children

of xsd:restriction specify the constraints on the type. For example, this xsd:simpleType element defines

amyYear as any year from 1974 on:

<xsd:simpleType name="myYear"> <xsd:restriction base="xsd:gYear"> <xsd:minInclusive value="1974"/> </xsd:restriction> </xsd:simpleType>

Then you declare the year element like this:

<xsd:element name="year" type="myYear" />

Facets

include: length, minLength, maxLength, pattern, enumeration, whiteSpace, maxInclusiv

Page 12: Chapter

e, maxExclusive, minInclusive, minExclusive, totalDigits,fractionDigits. Not all facets apply to all types.

For example, new string type must contain between 1 and 255 characters:

<?xml version="1.0"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:simpleType name="Str255"> <xsd:restriction base="xsd:string"> <xsd:minLength value="1"/> <xsd:maxLength value="255"/> </xsd:restriction> </xsd:simpleType> </xsd:schema>

For example, the new year type must be between 1974 and 2100:

<?xml version="1.0"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:simpleType name="myYear"> <xsd:restriction base="xsd:gYear"> <xsd:minInclusive value="1974"/> <xsd:maxInclusive value="2100"/> </xsd:restriction> </xsd:simpleType> </xsd:schema>

The enumeration facet lists all allowed values. Applies to all simple types except boolean. For example, the computer brand name must be one of the following : IBA JV, IBM, COMPAQ, DELL, HP.

<?xml version="1.0"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:simpleType name="computerBrandName"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="IBA JV"/> <xsd:enumeration value="IBM"/> <xsd:enumeration value="COMPAQ"/> <xsd:enumeration value="DELL"/> <xsd:enumeration value="HP"/> </xsd:restriction> </xsd:simpleType> </xsd:schema>

Each element in the xsd:all group must occur zero or once; that is minOccurs and maxOccurs must each be 0 or 1.

The xsd:all group must be the top level element of its type. The xsd:all group may contain only individual element declarations; no choices or sequences. Example:

<?xml version="1.0"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:complexType name="personName"> <xsd:all> <xsd:element name="firstName" type="xsd:string"/> <xsd:element name="lastName" type="xsd:string"/> </xsd:all> </xsd:complexType> </xsd:schema>

Page 13: Chapter

xsd:choice requires exactly one of a group of specified elements to appear. The choice can

have minOccurs and maxOccurs attributes that adjust this from zero to any given number. Example:

<?xml version="1.0"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:complexType name="computer"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:choice minOccurs="1" maxOccurs="1"> <xsd:element name="desktop" type="xsd:string"/> <xsd:element name="notebook" type="xsd:string"/> <xsd:element name="handheld" type="xsd:string"/> </xsd:choice> </xsd:sequence> </xsd:complexType> </xsd:schema>

hapter 2. SOAP 1.2 Web Service Standards

List and describe the encoding types used in a SOAP message.

• [SOAP_1.2_PART_2] SOAP Version 1.2 Part 2: Adjuncts

The SOAP encoding style is based on a simple type system that is a generalization of the common features found in type systems in programming languages, databases and semi-structured data. A type either is a simple (scalar) type or is a compound type constructed as a composite of several parts, each with a type. This is described in more detail below. This section defines rules for serialization of a graph of typed objects. It operates on two levels. First, given a schema in any notation consistent with the type system described, a schema for an XML grammar may be constructed. Second, given a type-system schema and a particular graph of values conforming to that schema, an XML instance may be constructed. In reverse, given an XML instance produced in accordance with these rules, and given also the original schema, a copy of the original value graph may be constructed.

There are following SOAP encoding types:

• Simple Types:

o Strings

o Enumerations

o Array of Bytes

• Compound Types:

o Arrays

o Structures

Simple Types

For simple types, SOAP adopts all the types found in the section "Built-in datatypes" of the "XML Schema Part 2: Datatypes" Specification, both the value and lexical spaces. Examples

include: boolean (true, false, 0 or 1), byte, short, int, long, float, double, string (java.lang.String), decimal(java.math.BigDecimal), date (java.util.GregorianCalendar), dateTime (java.util.Date), SOAP-ENC:base64 (byte []).

The following examples are a SOAP representation of these primitive data types:

<element name="age" type="int"/> <element name="height" type="float"/> <element name="displacement" type="negativeInteger"/> <element name="color"> <simpleType base="xsd:string"> <enumeration value="Green"/> <enumeration value="Blue"/>

Page 14: Chapter

</simpleType> </element> <age>45</age> <height>5.9</height> <displacement>-450</displacement> <color>Blue</color>

Strings

The datatype "string" is defined in "XML Schema Part 2: Datatypes" Specification. Note that this is not identical to the type called

"string" in many database or programming languages, and in particular may forbid some characters those languages would permit.

(Those values must be represented by using some datatype other than xsd:string.) A string MAY be encoded as a single-reference

or a multi-reference value. The containing element of the string value MAY have an "id" attribute. Additional accessor elements MAY then

have matching "href" attributes. For example, two accessors to the same string could appear, as follows:

<greeting id="String-0">Hello</greeting> <salutation href="#String-0"/>

However, if the fact that both accessors reference the same instance of the string (or subtype of string) is immaterial, they may be encoded as two single-reference values as follows:

<greeting>Hello</greeting> <salutation>Hello</salutation>

Schema fragments for these examples could appear similar to the following:

<element name="greeting" type="SOAP-ENC:string"/> <element name="salutation" type="SOAP-ENC:string"/>

(In this example, the type SOAP-ENC:string is used as the element's type as a convenient way to declare an element whose

datatype is "xsd:string" and which also allows an "id" and "href" attribute. See the SOAP Encoding schema for the exact definition. Schemas MAY use these declarations from the SOAP Encoding schema but are not required to.)

Enumerations

Enumeration as a concept indicates a set of distinct names. A specific enumeration is a specific list of distinct values appropriate to the base

type. For example the set of color names ("Green", "Blue", "Brown") could be defined as an enumeration based on

the string built-in type. The values ("1", "3", "5") are a possible enumeration based on integer, and so on. "XML Schema Part 2:

Datatypes" supports enumerations for all of the simple types except forboolean. The language of "XML Schema Part 1: Structures" Specification can be used to define enumeration types. If a schema is generated from another notation in which no specific base type is

applicable, use "string". In the following schema example "EyeColor" is defined as a string with the possible values of

"Green", "Blue", or "Brown" enumerated, and instance data is shown accordingly:

<element name="EyeColor" type="tns:EyeColor"/> <simpleType name="EyeColor" base="xsd:string"> <enumeration value="Green"/> <enumeration value="Blue"/> <enumeration value="Brown"/> </simpleType> <Person> <Name>Mikalai Zaikin</Name> <Age>34</Age> <EyeColor>Brown</EyeColor> </Person>

Array of Bytes

Page 15: Chapter

An array of bytes MAY be encoded as a single-reference or a multi-reference value. The rules for an array of bytes are similar to those for a

string. In particular, the containing element of the array of bytes value MAY have an "id" attribute. Additional accessor elements MAY then

have matching "href" attributes. The recommended representation of an opaque array of bytes is the 'base64' encoding defined in XML Schemas, which uses the base64 encoding algorithm. However, the line length restrictions that normally apply to base64 data in MIME

do not apply in SOAP. A "SOAP-ENC:base64" subtype is supplied for use with SOAP:

<picture xsi:type="SOAP-ENC:base64"> aG93IG5vDyBicm73biBjb3cNCg== </picture>

Polymorphic Accessor

Many languages allow accessors that can polymorphically access values of several types, each type being available at run time. A polymorphic

accessor instance MUST contain an "xsi:type" attribute that describes the type of the actual value. For example, a polymorphic

accessor named "cost" with a value of type "xsd:float" would be encoded as follows:

<cost xsi:type="xsd:float">29.95</cost>

as contrasted with a cost accessor whose value's type is invariant, as follows:

<cost>29.95</cost>

Compound types

A "struct" is a compound value in which accessor name is the only distinction among member values, and no accessor has the same name as any other.

An "array" is a compound value in which ordinal position serves as the only distinction among member values.

Structures

The members of a Compound Value are encoded as accessor elements. When accessors are distinguished by their name (as for example in a struct), the accessor name is used as the element name. Accessors whose names are local to their containing types have unqualified element

names; all others have qualified names. The following is an example of a struct of type "book":

<book> <author>Mikalai Zaikin</author> <title>SCDJWS 5.0 Study Guide</title> <intro>This is a certification guide</intro> </book>

And this is a schema fragment describing the above structure:

<xsd:element name="book"> <xsd:complexType> <xsd:sequence> <xsd:element name="author" type="xsd:string" /> <xsd:element name="title" type="xsd:string" /> <xsd:element name="intro" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element>

Arrays (SOAP 1.2)

Array encodings have been revised and simplified in the latest SOAP 1.2 specification.

Page 16: Chapter

ArrayType elements are derived from a generic nodeType element.

Now arrays have two attributes:

• itemType is the the type of the array (String, int, XML complex type).

• arraySize - The array's dimensions are represented by each item in the list of sizes (unspecified size in case of the asterisk). The number of items in the list represents the number of dimensions in the array. The asterisk, if present, MUST only appear in the first position in the list.

The default value of the arraySize attribute information item is "*", that is by default arrays are considered to have a single dimension of unspecified size.

<xs:attribute name="arraySize" type="tns:arraySize" /> <xs:attribute name="itemType" type="xs:QName" /> <xs:attributeGroup name="arrayAttributes"> <xs:attribute ref="tns:arraySize" /> <xs:attribute ref="tns:itemType" /> </xs:attributeGroup>

SOAP 1.1 array:

<numbers enc:arrayType="xs:int[2]"> <number>3</number> <number>4</number> </numbers>

SOAP 1.2 array:

<numbers enc:itemType="xs:int" enc:arraySize="2"> <number>3</number> <number>4</number> </numbers>

Arrays (SOAP 1.1)

In SOAP 1.1 arrays are defined as having a type of "SOAP-ENC:Array" or a type derived there from. Arrays are represented as element values, with no specific constraint on the name of the containing element (just as values generally do not constrain the name of their containing element). Arrays can contain elements which themselves can be of any type, including nested arrays. New types formed by

restrictions of SOAP-ENC:Array can also be created to represent, for example, arrays limited to integers or arrays of some user-defined enumeration. The representation of the value of an array is an ordered sequence of elements constituting the items of the array. Within an array value, element names are not significant for distinguishing accessors. Elements may have any name. In practice, elements will frequently be named so that their declaration in a schema suggests or determines their type. As with compound types generally, if the

value of an item in the array is a single-reference value, the item contains its value. Otherwise, the item references its value via an "href" attribute. The following example is a schema fragment and an array containing integer array members:

<element name="myFavoriteNumbers" type="SOAP-ENC:Array"/> <myFavoriteNumbers SOAP-ENC:arrayType="xsd:int[3]"> <number>1</number> <number>2</number> <number>3</number> </myFavoriteNumbers>

In that example, the array "myFavoriteNumbers" contains several members each of which is a value of type xsd:int. This

can be determined by inspection of the SOAP-ENC:arrayType attribute. Note that the SOAP-ENC:Array type allows

Page 17: Chapter

unqualified element names without restriction. These convey no type information, so when used they must either have

an xsi:type attribute or the containing element must have a SOAP-ENC:arrayType attribute. Naturally, types derived

from SOAP-ENC:Array may declare local elements, with type information. As previously noted, the SOAP-ENC schema contains declarations of elements with names corresponding to each simple type in the "XML Schema Part 2: Datatypes" Specification. It also

contains a declaration for "Array". Using these, we might write:

<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:int[3]"> <SOAP-ENC:int>1</SOAP-ENC:int> <SOAP-ENC:int>2</SOAP-ENC:int> <SOAP-ENC:int>3</SOAP-ENC:int> </SOAP-ENC:Array>

Arrays can contain instances of any subtype of the specified arrayType. That is, the members may be of any type that is substitutable

for the type specified in the arrayType attribute, according to whatever substitutability rules are expressed in the schema. So, for

example, an array of integers can contain any type derived from integer (for example "int" or any user-defined derivation of integer).

Similarly, an array of "address" might contain a restricted or extended type such as "internationalAddress". Because

the supplied SOAP-ENC:Array type admits members of any type, arbitrary mixtures of types can be contained unless specifically

limited by use of the arrayType attribute.

Array values may be structs or other compound values. For example an array of "my:order" structs :

<SOAP-ENC:Array SOAP-ENC:arrayType="my:order[2]"> <order> <product>Melon</product> <price>0.99</price> </order> <order> <product>Apple</product> <price>1.49</price> </order> </SOAP-ENC:Array>

Arrays may have other arrays as member values. The following is an example of an array of two arrays, each of which is an array of strings:

<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[][2]"> <item href="#array-1"/> <item href="#array-2"/> </SOAP-ENC:Array> <SOAP-ENC:Array id="array-1" SOAP-ENC:arrayType="xsd:string[3]"> <item>row1column1</item> <item>row1column2</item> <item>row1column3</item> </SOAP-ENC:Array> <SOAP-ENC:Array id="array-2" SOAP-ENC:arrayType="xsd:string[2]"> <item>row2column1</item> <item>row2column2</item> </SOAP-ENC:Array>

Arrays may be multi-dimensional. In this case, more than one size will appear within the asize part of the arrayType attribute:

<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[2,3]"> <item>row1column1</item> <item>row1column2</item> <item>row1column3</item> <item>row2column1</item> <item>row2ccolumn2</item> <item>row2column3</item> </SOAP-ENC:Array>

NOTE: According to WS-I BP 1.1 you MUST NOT use soapenc:Array type for array declarations

or soapenc:arrayType attribute in the type declarations (for both SOAP envelope and WSDL):

In a DESCRIPTION, declarations MUST NOT extend or restrict the soapenc:Array type.

Page 18: Chapter

In a DESCRIPTION, declarations MUST NOT use wsdl:arrayType attribute in the type declaration. In a DESCRIPTION, elements SHOULD NOT be named using the convention ArrayOfXXX. An ENVELOPE MUST NOT include the soapenc:arrayType attribute.

Mapping between XML Schema types and SOAP Java types

When a message part is defined using one of the XML Schema primitive types, the generated parameter's type is mapped to a corresponding Java native type. The same pattern is used when mapping elements that are defined within the scope of a complex type. The resulting field is of the corresponding Java native type.

The table below lists the mapping between XML Schema primitive types and Java native types:

Table 2.1. XML Schema Primitive Type to Java Native Type Mapping

XML Schema type SOAP Java type

xsd:string java.lang.String

xsd:integer java.math.BigInteger

xsd:int int

xsd:long long

xsd:short short

xsd:decimal java.math.BigDecimal

xsd:float float

xsd:double double

xsd:boolean boolean

xsd:byte byte

xsd:QName QName

xsd:dateTime XMLGregorianCalendar

xsd:base64Binary byte[]

xsd:hexBinary byte[]

xsd:unsignedInt long

xsd:unsignedShort int

xsd:unsignedByte short

xsd:time XMLGregorianCalendar

xsd:date XMLGregorianCalendar

xsd:g XMLGregorianCalendar

Wrapper Classes

Mapping XML Schema primitive types to Java primitive types does not work for all possible XML Schema constructs. Several cases require that an XML Schema primitive type is mapped to the Java primitive type's corresponding wrapper type. These cases include:

Page 19: Chapter

1. An element element with its nillable attribute set to true as shown:

2. 3. <element name="count" type="xsd:int" nillable="true" /> 4.

5. An element element with its minOccurs attribute set to 0 and its maxOccurs attribute set to 1, or

its maxOccurs attribute not specified, as shown:

6. 7. <element name="count" type="xsd:int" minOccurs="0" /> 8.

9. An attribute element with its use attribute set to optional, or not specified, and having neither

its default attribute nor its fixed attribute specified, as shown:

10. 11. <element name="date"> 12. <complexType> 13. <sequence/> 14. <attribute name="count" type="xsd:int" use="optional" /> 15. </complexType> 16. </element> 17.

Table below shows how XML Schema primitive types are mapped into Java wrapper classes in these cases:

Table 2.2. Primitive Schema Type to Java Wrapper Class Mapping

XML Schema type SOAP Java type

xsd:int java.lang.Integer

xsd:long java.lang.Long

xsd:short java.lang.Short

xsd:float java.lang.Float

xsd:double java.lang.Double

xsd:boolean java.lang.Boolean

xsd:byte java.lang.Byte

xsd:unsignedByte java.lang.Short

xsd:unsignedShort java.lang.Integer

xsd:unsignedInt java.lang.Long

xsd:unsignedLong java.math.BigInteger

NOTE: Element that is nillable, meaning that the element CAN BE EMPTY without causing a validation error. For each of the XML schema built-in types that map to a Java primitive, there is a corresponding Java primitive wrapper that can be used if

a nillable="true" attribute is specified.

Example of mapping XML Schema-Java class

XML Schema:

Page 20: Chapter

<schema> <complexType name="Address"> <sequence> <element name="street" nillable="true" type="xsd:string"/> <element name="city" nillable="true" type="xsd:string"/> <element name="state" nillable="true" type="xsd:string"/> <element name="zip" type="xsd:int"/> </sequence> </complexType> </schema>

Java class:

public class Address { public String street; public String city; public String state; public int zip; }

NOTE: Since zip is not nillable, it can be primitive, otherwise it would be:

XML Schema:

<schema> <complexType name="Address"> <sequence> <element name="street" nillable="true" type="xsd:string"/> <element name="city" nillable="true" type="xsd:string"/> <element name="state" nillable="true" type="xsd:string"/> <element name="zip" nillable="true" type="xsd:int"/> </sequence> </complexType> </schema>

Java class:

public class Address { public String street; public String city; public String state; public Integer zip; }

In XML Schema, we can use nillable attribute to indicate that whether the element's content could be nil, as

in <xsd:element name="birthDate" type="xsd:date" nillable="true"/>. If the content

of an element is nil, we can use xsi:nil attribute to signal the processor, as in <birthDate xsi:nil="true" /> and this element must not contain any content.

More examples on nillable attribute. Consider following XML Schema:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="rootElement" nillable="true"> <xsd:complexType> <xsd:sequence> <xsd:element name="myElement" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema>

VALID:

<rootElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <myElement>I am valid</myElement> </rootElement>

VALID:

Page 21: Chapter

<rootElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />

INVALID (when xsi:nil is true, the element MUST BE EMPTY):

<rootElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"> <myElement>I am NOT valid</myElement> </rootElement>

INVALID (element rootElement MUST have myElement child and xsi:nil has not been set to true):

<rootElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />

Mapping arbitrary XML content to Java

The <xsd:any/> element is an element that represents arbitrary XML content within an XML document. It is what its name indicates: any kind of XML. This lets you create complex type definitions in an XML Schema without describing what the exact structure of certain parts

of the complex type is. Here is an example that shows the definition of a type called Order. It contains two regular elements and

one <xsd:any/> element:

<schema elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema"> <complexType name="Order"> <sequence> <element name="date" nillable="true" type="xsd:dateTime"/> <element name="customer" nillable="true" type="xsd:string"/> <xsd:any maxOccurs="unbounded"/> </sequence> </complexType> </schema>

An instance of this type can contain any number of additional XML elements without violating the schema definition. You can add additional

information to anOrder element without defining its format in the schema. The JAX-RPC 1.1 specification defines

that <xsd:any/> element is mapped to the SAAJ'sjavax.xml.soap.SOAPElement interface. This means that the

Service Endpoint Interface [SEI] will contain a parameter or return value of typejavax.xml.soap.SOAPElement for each

place in the schema where <xsd:any/> was used and, respectively, javax.xml.soap.SOAPElement[] if

the maxOccursattribute is bigger than 1. Therefore, a JAX-RPC tool will generate the following class from the sample schema above:

public class Order implements java.io.Serializable { private java.util.GregorianCalendar date; private java.lang.String customer; private javax.xml.soap.SOAPElement[] _any; ... }

This approach can be usefule when your Web service uses some data that you don't want to be mapped into a Java class, but rather want to let the JAX-RPC engine hand it to the implementation in its XML form. The implementation could then parse it or simply pass it on as XML for

further processing in the backend application. Similarly, you can create a client proxy that lets you pass in a SOAPElement rather than a mapped Java object.

Describe the SOAP Processing and Extensibility Model.

• [SOAP_1.2_PART_1] SOAP Version 1.2 Part 1: Messaging Framework

SOAP Processing Model

Page 22: Chapter

SOAP provides a distributed processing model that assumes a SOAP message originates at an initial SOAP sender and is sent to an ultimate SOAP receiver via zero or more SOAP intermediaries. Note that the SOAP distributed processing model can support many Message Exchange Patterns (MEPs) including but not limited to one-way messages, request/response interactions, and peer-to-peer conversations.

The SOAP processing model specifies how a SOAP receiver processes a SOAP message. It applies to a single message only, in isolation from any other SOAP message. The SOAP processing model itself does not maintain any state or perform any correlation or coordination between messages, even, for example, when used in combination with a SOAP feature which involves sending multiple SOAP messages in sequence, each subsequent message depending on the response to the previous message. It is the responsibility of each such feature to define any combined processing.

SOAP Nodes

A SOAP node can be the initial SOAP sender, an ultimate SOAP receiver, or a SOAP intermediary. A SOAP node receiving a SOAP message MUST perform processing according to the SOAP processing model as described in this section and in the remainder of this specification. A SOAP node is identified by a URI.

SOAP Roles and SOAP Nodes

In processing a SOAP message, a SOAP node is said to act in one or more SOAP roles, each of which is identified by a URI known as the SOAP role name. The roles assumed by a node MUST be invariant during the processing of an individual SOAP message. This specification deals only with the processing of individual SOAP messages. No statement is made regarding the possibility that a given SOAP node might or might not act in varying roles when processing more than one SOAP message.

Table below defines three role names which have special significance in a SOAP message:

Table 2.3. SOAP Roles defined by SOAP 1.2 specification

Short-name Name Description

next "http://www.w3.org/2003/05/soap-envelope/role/next"

Each SOAP intermediary and the ultimate SOAP receiver MUST act in this role.

none "http://www.w3.org/2003/05/soap-envelope/role/none"

SOAP nodes MUST NOT act in this role.

ultimateReceiver "http://www.w3.org/2003/05/soap-envelope/role/ultimateReceiver"

The ultimate receiver MUST act in this role.

In addition to the SOAP role names defined in the table, other role names MAY be used as necessary to meet the needs of SOAP applications.

Targeting SOAP Header Blocks

A SOAP header block MAY carry a role attribute information item that is used to target the header block at SOAP nodes operating in the

specified role. SOAP 1.2 specification refers to the value of the SOAP role attribute information item as the SOAP role for the corresponding SOAP header block.

A SOAP header block is said to be targeted at a SOAP node if the SOAP role for the header block is the name of a role in which the SOAP node

operates. SOAP header blocks targeted at the special role "http://www.w3.org/2003/05/soap-envelope/role/none" are never formally processed. Such SOAP header blocks MAY carry data that is required for processing of other SOAP header blocks. Unless removed by the action of an intermediary, such blocks are relayed with the message to the ultimate receiver.

Understanding SOAP Header Blocks

A SOAP header block MAY carry a mustUnderstand attribute information item. When the value of such an attribute information

item is "true", the SOAP header block is said to be mandatory.

Mandatory SOAP header blocks are presumed to somehow modify the semantics of other SOAP header blocks or SOAP body elements. Therefore, for every mandatory SOAP header block targeted to a node, that node MUST either process the header block or not process the SOAP message at all, and instead generate a fault. Tagging SOAP header blocks as mandatory thus assures that such modifications will not be silently (and, presumably, erroneously) ignored by a SOAP node to which the header block is targeted.

Processing SOAP Messages

Page 23: Chapter

Unless otherwise stated, processing of all generated SOAP messages, SOAP faults and application-level side effects MUST be semantically equivalent to performing the following steps separately, and in the order given:

1. Determine the set of roles in which the node is to act. The contents of the SOAP envelope, including any SOAP header blocks and the SOAP body, MAY be inspected in making such determination.

2. Identify all header blocks targeted at the node that are mandatory. 3. If one or more of the SOAP header blocks identified in the preceding step are not understood by the node then generate a single

SOAP fault with theValue of Code set to "env:MustUnderstand". If such a fault is generated, any further processing MUST NOT be done. Faults relating to the contents of the SOAP body MUST NOT be generated in this step.

4. Process all mandatory SOAP header blocks targeted at the node and, in the case of an ultimate SOAP receiver, the SOAP body. A SOAP node MAY also choose to process non-mandatory SOAP header blocks targeted at it.

5. In the case of a SOAP intermediary, and where the SOAP message exchange pattern and results of processing (e.g., no fault generated) require that the SOAP message be sent further along the SOAP message path, relay the message.

Relaying SOAP Messages

A SOAP header block MAY carry a relay attribute information item. When the value of such an attribute information item is "true", the header block is said to be relayable.

Forwarding SOAP intermediaries MUST process the message according to the SOAP processing model defined in "Processing SOAP Messages". In addition, when generating a SOAP message for the purpose of forwarding, they MUST:

1. Remove all processed SOAP header blocks. 2. Remove all non-relayable SOAP header blocks that were targeted at the forwarding node but ignored during processing. 3. Retain all relayable SOAP header blocks that were targeted at the forwarding node but ignored during processing.

SOAP Versioning Model

The version of a SOAP message is identified by the XML expanded name of the child element information item of the document information item. A SOAP Version 1.2 message has a child element information item of the document information item with a [local name]

of Envelope and a [namespace name] of"http://www.w3.org/2003/05/soap-envelope".

If a SOAP node receives a message whose version is not supported it MUST generate a fault with a Value of Code set

to "env:VersionMismatch". Any other malformation of the message construct MUST result in the generation of a fault with

a Value of Code set to "env:Sender".

The example below shows a version mismatch SOAP fault generated by a SOAP Version 1.2 node as a result of receiving a SOAP/1.1

message. The fault message is a SOAP/1.1 message with an Upgrade SOAP header block indicating support for SOAP Version 1.2:

<?xml version="1.0" ?> <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Header> <env:Upgrade> <env:SupportedEnvelope qname="ns1:Envelope" xmlns:ns1="http://www.w3.org/2003/05/soap-envelope"/> </env:Upgrade> </env:Header> <env:Body> <env:Fault> <faultcode>env:VersionMismatch</faultcode> <faultstring>Version Mismatch</faultstring> </env:Fault> </env:Body> </env:Envelope>

Let's start by looking at a basic SOAP message and its nested elements.

<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> <env:Header> <pns:qualityOfService xmlns:pns="http://example.org/qos"> <pns:priority>3</pns:priority> <pns:timestamp>2004-02-25T01:00:00-00:00</pns:timestamp> <pns:persist>true</pns:persist> </pns:appHeaderBlock> </env:Header> <env:Body> <bmns:businessPO xmlns:env="http://example.org/po"> <bmns:description>Widgets</bmns:description>

Page 24: Chapter

<bmns:quantity>100</bmns:quantity> <bmns:price>20.5</bmns:price> </bmns:businessPO> </env:Body> </env:Envelope>

The outermost element is the env:Envelope that includes the namespace URL for SOAP. Enclosed within this are two subelements

that SOAP defines. These are the env:Header and env:Body elements. SOAP does not define their contents. The elements are specific to the application that creates and processes the SOAP message. However, the SOAP specification does define how a SOAP node processes these elements.

The env:Header element is OPTIONAL in SOAP, but it has been included in the sample to illustrate its use. The SOAP header is an extension mechanism that provides a way for information to be passed within a SOAP message that is not part of the business message

payload. In the previous example, theenv:Header includes an immediate child element that contains a set of quality of service parameters. This immediate child is called a header block. A header can contain many header blocks. The header block has its own XML

namespace in which the priority, timestamp, and persist elements appear. The SOAP specification allows header blocks to be targeted at specific SOAP nodes for processing as the message travels along its message path. The SOAP headers control and process a message as it moves along a message path. They include information that controls messaging qualities of service such as security, reliability, and addressing. By specifying new headers, you can create interoperable protocols based on SOAP. These form the basis of the services architecture.

The env:Body element within the SOAP message is MANDATORY. It contains the payload of the message, which is the information that is being transferred from the initial SOAP sender to the ultimate SOAP receiver. The choice of what information goes into

the env:Header and what goes into the env:Bodyelements is a matter of business application and system design. In a typical enterprise environment, middleware that supports a defined set of service policies mandates what headers are required in a SOAP message.

The env:Body is then used to contain necessary application-specific information, which is processed by the ultimate receiver of the remote service implemention.

The "role" Attribute

When a SOAP node processes a SOAP message, the node is said to act in one of several roles. A SOAP role identifies how a SOAP node should process a message. A URI identifies the SOAP role. It might be one of the three roles within the SOAP specification or one that systems designers assign to meet the needs of some applications. It appears as an attribute on the parent header block element:

<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> <env:Header> <hb1:firstHeaderBlock xmlns:hb1="http://example.org/hb1" env:role="http://example.org/Qos"> ..... </hb1:firstHeaderBlock> <hb2:secondHeaderBlock xmlns:hb1="http://example.org/hb2" env:role="http://www.w3.org/2003/05/soap-envelope/role/next"> ..... </hb2:secondHeaderBlock> <hb3:thirdHeaderBlock xmlns:hb1="http://example.org/hb3"> ..... </hb3:thirdHeaderBlock> </env:Header> <env:Body> ..... </env:Body> </env:Envelope>

The hb1:firstHeaderBlock element has a role attribute set to a value of http://example.org/Qos. The system designer assumes that the SOAP node that plays this role uses the information within the header block to manage message delivery

quality of service in some specified way. The second header blockhb2:secondHeaderBlock has its role attribute set to one of the roles defined within the SOAP 1.2 specification. The SOAP 1.2 specification defines three roles:

• http://www.w3.org/2003/05/soap-envelope/role/none

If a header block has a role set to the "none" URI, no SOAP node should process the contents of the header block. Nodes might need to examine the header contents if another header block references them, but they should not be processed.

• http://www.w3.org/2003/05/soap-envelope/role/next

Page 25: Chapter

Every SOAP node must be capable of processing a header block with its role attribute set to the "next" URI, because this is a

role that every node should assume. A header block with a role set to the "next" URI is one that the next SOAP node in the

message path should examine and possibly process. In the previous example, the hb2:secondHeaderBlock has

its role attribute set to "next".

• http://www.w3.org/2003/05/soap-envelope/role/ultimateReceiver

A SOAP node that assumes the role of an ultimate SOAP receiver processes a header block with its role attribute set to

the "ultimateReceiver" URI. A header block that has no role attribute is targeted at the SOAP node that is acting

as an ultimate SOAP receiver. In the example, thehb3:thirdHeaderBlock is targeted at the ultimate SOAP receiver because it doesn't have a role attribute.

NOTE: SOAP 1.1 has the actor attribute. In SOAP 1.2 this attribute is renamed to role. The semantics of the attribute are unchanged.

The "mustUnderstand" Attribute

Sometimes a SOAP node MUST process a particular header completely if it is acting in that SOAP role. The SOAP specification signals this

condition by introducing a "mustUnderstand" attribute that can be added to a header block:

<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> <env:Header> <hb1:firstHeaderBlock exmlns:hb1="http://example.org/hb1" env:role="http://example.org/Qos" env:mustUnderstand="1"> ..... </hb1:firstHeaderBlock> <hb2:secondHeaderBlock xmlns:hb1="http://example.org/hb2" env:role="http://www.w3.org/2003/05/soap-envelope/role/next"> ..... </hb2:secondHeaderBlock> <hb3:thirdHeaderBlock xmlns:hb1="http://example.org/hb3"> ..... </hb3:thirdHeaderBlock> </env:Header> <env:Body> ..... </env:Body> </env:Envelope>

In the example, the SOAP node that is targeted by the hb1:firstHeaderBlock element must process the header block

because a "mustUnderstand" attribute is set to 1. This is commonly referred to as a mandatory header block. The SOAP processing model states that processing of a SOAP message must not start until a SOAP node has identified all the mandatory header blocks targeted at it and is prepared to process them in accordance with the specification for those header blocks. If a header block has

a "mustUnderstand" attribute set to 0, or there is no such attribute, a SOAP node might choose to ignore and not process the

header block, even though it might be targeted at it. If a header block has a "mustUnderstand" attribute and is targeted at a SOAP node, the SOAP node is obliged to generate and return a SOAP fault if it is unable to process the header block.

NOTE: According to Basic Profile Version 1.1:

An ENVELOPE containing a soap:mustUnderstand attribute MUST only use the lexical forms "0" and "1".

env:mustUnderstand="0|1"

The "relay" Attribute

The SOAP processing model states that a node that processes a header must remove it from the message before passing it to another node along the message path. This is because the SOAP specification errs on the side of caution, making sure that an intermediary makes no assumptions about what will happen to the message header it has processed later in the message path. The SOAP specification does, however, allow a node to reinsert a header into an outbound message with its contents unchanged or altered in some way, but the default behavior of the node is to remove the header after processing.

Page 26: Chapter

Sometimes, however, a systems designer wants a particular header to be targeted at any or all nodes within a message path. To allow this,

SOAP 1.2 introduces the "relay" attribute. If this attribute is set to true, a SOAP node that detects a header targeted at itself can forward the header block to the next node if it chooses not to process it.

<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> <env:Header> <hb1:firstHeaderBlock xmlns:hb1="http://example.org/hb1" env:role="http://example.org/Qos" env:mustUnderstand="1"> ..... </hb1:firstHeaderBlock> <hb2:secondHeaderBlock xmlns:hb1="http://example.org/hb2" env:role="http://www.w3.org/2003/05/soap-envelope/role/next" env:relay="true"> ..... </hb2:secondHeaderBlock> <hb3:thirdHeaderBlock xmlns:hb1="http://example.org/hb3"> ..... </hb3:thirdHeaderBlock> </env:Header> <env:Body> ..... </env:Body> </env:Envelope>

In the example, the second header block is targeted at the "next" node in the message path. It also has the "relay" attribute set

to true. This means that a SOAP node that receives this message can process the header if it understands it. If it does so, the SOAP

processing rules must be obeyed and the header removed before forwarding the entire message. A "relay" attribute set

to true means that the node, if it chooses to, can ignore the header block and forward it to the next node. Remember that if a header

block also has the "mustUnderstand" attribute set to true, this over-rules a "relay", and the node must process the header block if it understands its meaning.

NOTE: According to SOAP Version 1.2 Part 1: Messaging Framework:

If relaying the message, a SOAP intermediary MAY substitute "true" for the value "1", or "false" for "0". In addition, a

SOAP intermediary MAY omit a SOAPmustUnderstand attribute information item if its value is "0".

SOAP Extensibility Model

SOAP provides a simple messaging framework whose core functionality is concerned with providing extensibility. The extensibility mechanisms can be used to add capabilities found in richer messaging environments.

SOAP Features

A SOAP feature is an extension of the SOAP messaging framework. Although SOAP poses no constraints on the potential scope of such features, example features may include "reliability", "security", "correlation", "routing", and message exchange patterns (MEPs) such as request/response, one-way, and peer-to-peer conversations.

The SOAP extensibility model provides two mechanisms through which features can be expressed: the SOAP Processing Model (describes the behavior of a single SOAP node with respect to the processing of an individual message) and the SOAP Protocol Binding Framework (mediates the act of sending and receiving SOAP messages by a SOAP node via an underlying protocol).

SOAP Message Exchange Patterns (MEPs)

A Message Exchange Pattern (MEP) is a template that establishes a pattern for the exchange of messages between SOAP nodes. MEPs are a type of feature, and unless otherwise stated, references in this specification to the term "feature" apply also to MEPs. The request-response MEP specified in SOAP 1.2 Part 2 [SOAP Part 2] illustrates the specification of a MEP feature.

The specification of a message exchange pattern MUST:

1. Provide a URI to name the MEP. 2. Describe the life cycle of a message exchange conforming to the pattern. 3. Describe the temporal/causal relationships, if any, of multiple messages exchanged in conformance with the pattern (e.g.,

responses follow requests and are sent to the originator of the request.) 4. Describe the normal and abnormal termination of a message exchange conforming to the pattern.

SOAP Modules

Page 27: Chapter

The term "SOAP module" refers to the specification of the syntax and semantics of one or more SOAP header blocks. A SOAP module realizes zero or more SOAP features. A module specification adheres to the following rules. It:

1. MUST identify itself with a URI. This enables the module to be unambiguously referenced in description languages or during negotiation.

2. MUST declare the features provided by a module. 3. MUST clearly and completely specify the content and semantics of the SOAP header blocks used to implement the behavior in

question, including if appropriate any modifications to the SOAP processing model. The SOAP extensibility model does not limit the extent to which SOAP can be extended. Nor does it prevent extensions from modifying the SOAP processing model.

4. MAY utilize the property conventions defined in SOAP 1.2 Part 2 [SOAP Part 2], section A Convention for Describing Features and Bindings, in describing the functionality that the module provides. If these conventions are followed, the module specification MUST clearly describe the relationship between the abstract properties and their representations in the SOAP envelope. Note that it is possible to write a feature specification purely in terms of abstract properties, and then write a separate module specification which implements that feature, mapping the properties defined in the feature specification to SOAP header blocks in the SOAP module.

5. MUST clearly specify any known interactions with or changes to the interpretation of the SOAP body. Furthermore, it MUST clearly specify any known interactions with or changes to the interpretation of other SOAP features and SOAP modules. For example, we can imagine a module which encrypts and removes the SOAP body, inserting instead a SOAP header block containing a checksum and an indication of the encryption mechanism used. The specification for such a module would indicate that the decryption algorithm on the receiving side is to be run prior to any other modules which rely on the contents of the SOAP body.

Describe SOAP Message Construct and create a SOAP message that contains an attachment.

• [SOAP_1.2_PART_1] SOAP Version 1.2 Part 1: Messaging Framework

A SOAP message is an XML document that consists of a mandatory SOAP envelope, an optional SOAP header, and a mandatory SOAP body.

The namespace identifier for the elements and attributes from SOAP message is

"http://www.w3.org/2003/05/soap-envelope". A SOAP message contains the following:

• The Envelope is the top element of the XML document representing the message.

• The Header is a generic mechanism for adding features to a SOAP message in a decentralized manner without prior agreement between the communicating parties. SOAP defines a few attributes that can be used to indicate who should deal with a

feature and whether it is optional or mandatory. NOTE: Header element is OPTIONAL.

• The Body is a container for mandatory information intended for the ultimate recipient of the message. SOAP defines one

element for the body, which is the Fault element used for reporting errors. NOTE: Body element is MANDATORY and MUST be exactly 1 per message.

The grammar rules are as follows:

1. Envelope

• The element name is "Envelope".

• The element MUST be present in a SOAP message.

• One or two element information items in its [children] property in order as follows:

a. An optional Header element information item.

b. A mandatory Body element information item.

SOAP 1.2 Schema for Envelope:

<xs:complexType name="Envelope"> <xs:sequence> <xs:element ref="tns:Header" minOccurs="0"/> <xs:element ref="tns:Body" minOccurs="1"/> </xs:sequence> <xs:anyAttribute namespace="##other" processContents="lax"/> </xs:complexType>

Example:

Page 28: Chapter

<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> <env:Header> <n:alertcontrol xmlns:n="http://example.org/alertcontrol"> <n:priority>1</n:priority> <n:expires>2001-06-22T14:00:00-05:00</n:expires> </n:alertcontrol> </env:Header> <env:Body> <m:alert xmlns:m="http://example.org/alert"> <m:msg>Pick up Mary at school at 2pm</m:msg> </m:alert> </env:Body> </env:Envelope>

NOTE: SOAP 1.1 allows additional elements to follow the SOAP Body element, SOAP 1.2 DISALLOWS these.

NOTE: According to WS-I BP 1.1:

An ENVELOPE MUST NOT have any element children of soap:Envelope following the soap:Body element.

2. Header

• The element name is "Header".

• The element MAY be present in a SOAP message. If present, the element MUST be the first immediate child element

of a SOAP Envelopeelement.

• The element MAY contain a set of header entries each being an immediate child element of the

SOAP Header element. All immediate child elements of the SOAP Header element MUST be namespace-qualified.

NOTE: WS-I BP 1.0 requires all immediate children of Header element be namespace qualified.

3. SOAP 1.2 Schema for Header:

4. 5. <xs:complexType name="Header"> 6. <xs:annotation> 7. <xs:documentation> 8. Elements replacing the wildcard MUST be namespace qualified, but can be in the

targetNamespace 9. </xs:documentation> 10. </xs:annotation> 11. <xs:sequence> 12. <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/> 13. </xs:sequence> 14. <xs:anyAttribute namespace="##other" processContents="lax"/> 15. </xs:complexType> 16. 17.

18. Example:

19. 20. <env:Header xmlns:env="http://www.w3.org/2003/05/soap-envelope" > 21. <t:Transaction xmlns:t="http://example.org/2001/06/tx" env:mustUnderstand="1" > 22. 5 23. </t:Transaction> 24. </env:Header> 25. 26.

27. Body

• The element name is "Body".

• The element MUST be present in a SOAP message and MUST be an immediate child element of a

SOAP Envelope element. It MUST directly follow the SOAP Header element if present. Otherwise it MUST

be the first immediate child element of the SOAP Envelope element.

• The element MAY contain a set of body entries each being an immediate child element of the SOAP Body element.

Immediate child elements of the SOAP Body element SHOULD be namespace-qualified.

SOAP defines one particular direct child of the SOAP body, the SOAP fault, which is used for reporting errors.

Page 29: Chapter

NOTE: WS-I BP 1.1 requires ALL immediate children of Body element be namespace qualified:

The children of the soap:Body element in an ENVELOPE MUST be namespace qualified.

28. SOAP 1.2 Schema for Body:

29. 30. <xs:complexType name="Body"> 31. <xs:sequence> 32. <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/> 33. </xs:sequence> 34. <xs:anyAttribute namespace="##other" processContents="lax"/> 35. </xs:complexType> 36. 37.

38. Example:

39. 40. <env:Body xmlns:env="http://www.w3.org/2003/05/soap-envelope"> 41. <m:alert xmlns:m="http://example.org/alert"> 42. <m:msg>Pick up Mary at school at 2pm</m:msg> 43. </m:alert> 44. </env:Body> 45. 46.

The SOAP Body element provides a simple mechanism for exchanging mandatory information intended for the ultimate recipient of the

message. Typical uses of the Body element include marshalling RPC calls and error reporting. The Body element is encoded as an

immediate child element of the SOAP Envelope XML element.

If a Header element is present then the Body element MUST immediately follow the Header element, otherwise it MUST be the

first immediate child element of the Envelope element. All immediate child elements of the Body element are called body entries

and each body entry is encoded as an independent element within the SOAP Body element. The encoding rules for body entries are as follows:

1. WS-I BP 1.1: The children of the soap:Body element in an ENVELOPE MUST be namespace qualified.

WS-I BP 1.1: An ENVELOPE MUST NOT contain soap:encodingStyle attributes on any element that is a child

of soap:Body.

2. WS-I BP 1.1: An ENVELOPE described in an rpc-literal binding MUST NOT

contain soap:encodingStyle attribute on any element that is a grandchild of soap:Body.

SOAP Fault

SOAP defines one body entry, which is the Fault entry used for reporting errors. Here is SOAP 1.2 Schema definition

of Fault element:

<xs:complexType name="Fault" final="extension"> <xs:annotation> <xs:documentation> Fault reporting structure </xs:documentation> </xs:annotation> <xs:sequence> <xs:element name="Code" type="tns:faultcode"/> <xs:element name="Reason" type="tns:faultreason"/> <xs:element name="Node" type="xs:anyURI" minOccurs="0"/> <xs:element name="Role" type="xs:anyURI" minOccurs="0"/> <xs:element name="Detail" type="tns:detail" minOccurs="0"/> </xs:sequence> </xs:complexType>

Page 30: Chapter

Sample SOAP 1.2 fault is shown below:

<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:flt="http://example.org/faults"> <env:Body> <env:Fault> <env:Code> <env:Value>env:Receiver</env:Value> <env:Subcode> <env:Value>flt:BadValue</env:Value> </env:Subcode> </env:Code> <env:Reason> <env:Text>A Fault occurred</env:Text> </env:Reason> <env:Detail> <flt:MyDetails> <flt:Message>Something went wrong at the Receiver</flt:Message> <flt:ErrorCode>1234</flt:ErrorCode> </flt:MyDetails> </env:Detail> </env:Fault> </env:Body> </env:Envelope>

The SOAP Fault element is used to carry error and/or status information within a SOAP message. If present, the SOAP Fault element

MUST appear as a body entry and MUST NOT appear more than once within a Body element. The SOAP Fault element defines two or more child element information items in its [children] property in order as follows:

1. A MANDATORY Code element.

2. 3. <xs:element name="Code" type="tns:faultcode"/> 4. ... 5. <xs:complexType name="faultcode"> 6. <xs:sequence> 7. <xs:element name="Value" type="tns:faultcodeEnum"/> 8. <xs:element name="Subcode" type="tns:subcode" minOccurs="0"/> 9. </xs:sequence> 10. </xs:complexType> 11. 12.

The Code element information item has:

• A [local name] of Code.

• One or two child element information items in its [children] property, in order, as follows:

a. A MANDATORY Value element information item.

The type of the Value element information item is env:faultCodeEnum. SOAP 1.2 defines a small set of SOAP fault codes covering high level SOAP faults:

<xs:element name="Value" type="tns:faultcodeEnum"/> ... <xs:simpleType name="faultcodeEnum"> <xs:restriction base="xs:QName"> <xs:enumeration value="tns:DataEncodingUnknown"/> <xs:enumeration value="tns:MustUnderstand"/> <xs:enumeration value="tns:Receiver"/> <xs:enumeration value="tns:Sender"/> <xs:enumeration value="tns:VersionMismatch"/> </xs:restriction> </xs:simpleType>

b. An OPTIONAL Subcode element information item.

c.

Page 31: Chapter

d. <xs:element name="Subcode" type="tns:subcode" minOccurs="0"/> e. ... f. <xs:complexType name="subcode"> g. <xs:sequence> h. <xs:element name="Value" type="xs:QName"/> i. <xs:element name="Subcode" type="tns:subcode" minOccurs="0"/> j. </xs:sequence> k. </xs:complexType> l.

The Subcode element information item has:

o A [local name] of Subcode.

o One or two child element information items in its [children] property, in order, as follows:

i. A MANDATORY Value element information item.

The type of the Value element information item is xs:QName. The value of this element is an application defined subcategory of the value of

the Value child element information item of the Subcode element information item's parent element information item.

ii. An optional Subcode element information item.

13. A MANDATORY Reason element information item.

The Reason element information item is intended to provide a human-readable explanation of the fault.

<xs:element name="Reason" type="tns:faultreason"/> ... <xs:complexType name="faultreason"> <xs:sequence> <xs:element name="Text" type="tns:reasontext" minOccurs="1" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType>

The Reason element information item has:

• A [local name] of Reason.

• One or more Text element information item children.

Each child Text element information item MUST have a mandatory attribute information item with a [local name]

of lang and [namespace name] of "http://www.w3.org/XML/1998/namespace".

Note that the definition in of the lang attribute information item requires that the [prefix] is "xml"or any capitalization thereof.

Each child Text element information item SHOULD have a different value for its xml:lang attribute information item.

<xs:element name="Text" type="tns:reasontext" minOccurs="1" maxOccurs="unbounded"/> ... <xs:complexType name="reasontext"> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute ref="xml:lang" use="required"/> </xs:extension> </xs:simpleContent> </xs:complexType>

Page 32: Chapter

14. An OPTIONAL Node element information item.

The Node element information item is intended to provide information about which SOAP node on the SOAP message path caused the fault to happen.

The type of the Node element information item is xs:anyURI.

<xs:element name="Node" type="xs:anyURI" minOccurs="0"/>

Each SOAP node is identified by a URI. The value of the Node element information item is the URI that identifies the SOAP node that generated the fault. SOAP nodes that do not act as the ultimate SOAP receiver MUST include this element information item. An ultimate SOAP receiver MAY include this element information item to indicate explicitly that it generated the fault.

15. An OPTIONAL Role element information item.

The Role element information item identifies the role the node was operating in at the point the fault occurred.

The type of the Role element information item is xs:anyURI.

<xs:element name="Role" type="xs:anyURI" minOccurs="0"/>

The value of the Role element information item MUST be one of the roles assumed by the node during processing of the message.

16. An OPTIONAL Detail element information item.

The Detail element information item is intended for carrying application specific error information.

<xs:element name="Detail" type="tns:detail" minOccurs="0"/> ... <xs:complexType name="detail"> <xs:sequence> <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> <xs:anyAttribute namespace="##other" processContents="lax"/> </xs:complexType>

The Detail element information item MAY have any number of character information item children. The character code of each such character information item MUST be amongst the white space characters as defined by XML 1.0. These are considered significant.

The Detail element information item MAY be present in a SOAP fault in which case it carries additional information relative

to the SOAP fault codes describing the fault. For example, the Detail element information item might contain information

about a message not containing the proper credentials, a timeout, etc. The presence of the Detail element information item has no significance as to which parts of the faulty SOAP message were processed.

SOAP 1.1 allows extension of fault codes using a "dot" notation, SOAP 1.2 disallows this and provides a more XML-like representation instead.

SOAP 1.1 fault:

Page 33: Chapter

<e:Fault> <faultcode>e:Server.Memory</faultcode> <faultstring>Out of memory</faultstring> </e:Fault>

SOAP 1.2 fault:

<e:Fault> <e:Code> <e:Value>e:Receiver</e:Value> <e:Subcode> <e:Value>p:Memory</e:Value> </e:Subcode> </e:Code> <e:Reason>Out of memory</e:Reason> </e:Fault>

SOAP Fault Codes

SOAP fault codes are XML expanded names, and are intended to provide a means by which faults are classified. A hierarchical list of SOAP codes and associated supporting information is included in every SOAP fault message, with each such code identifying the fault category at an increasing level of detail.

The values of the Value child element information item of the Code element information item are RESTRICTED to those defined by

the env:faultCodeEnumtype (see the table below). Additional fault subcodes MAY be created for use by applications or features.

Such subcodes are carried in the Value child element information item of the Subcode element information item.

SOAP fault codes are to be interpreted as modifiers of the contents of the Detail element information item in the sense that they

provide the context for the Detail element information item. A SOAP node MUST understand all SOAP fault codes in a SOAP fault

message in order to be able to interpret theDetail element information item in a SOAP fault.

Sample SOAP fault where the Detail element information item is to be interpreted in the context of

the "env:Sender" and "m:MessageTimeout" fault codes:

<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:m="http://www.example.org/timeouts" xmlns:xml="http://www.w3.org/XML/1998/namespace"> <env:Body> <env:Fault> <env:Code> <env:Value>env:Sender</env:Value> <env:Subcode> <env:Value>m:MessageTimeout</env:Value> </env:Subcode> </env:Code> <env:Reason> <env:Text xml:lang="en">Sender Timeout</env:Text> </env:Reason> <env:Detail> <m:MaxTime>P5M</m:MaxTime> </env:Detail> </env:Fault> </env:Body> </env:Envelope>

NOTE: WS-I BP 1.1 PROHIBITS the use of "dot" notation of fault code (e.g. Server.Memory, or Sender.Memory).

The set of predefined fault code values is:

Table 2.4. SOAP Fault Codes

Page 34: Chapter

Local Name Meaning

VersionMismatch

The faulting node found an invalid element information item instead of the

expected Envelope element information item. The namespace, local name or both did

not match the Envelope element information item required by this recommendation.

MustUnderstand

An immediate child element information item of the SOAP Header element information

item targeted at the faulting node that was not understood by the faulting node contained a

SOAP mustUnderstand attribute information item with a value of "1".

DataEncodingUnknown

A SOAP header block or SOAP body child element information item targeted at the faulting SOAP node is scoped with a data encoding that the faulting node does not support.

DataEncodingUnknown generated when a received message uses an

unrecognised value of the encodingStyleattribute.

Sender

The message was incorrectly formed or did not contain the appropriate information in order to succeed. For example, the message could lack the proper authentication or payment information. It is generally an indication that the message is not to be resent without change.

NOTE: The SOAP 1.1 "Client" fault code is renamed "Sender" in SOAP 1.2.

Receiver

The message could not be processed for reasons attributable to the processing of the message rather than to the contents of the message itself. For example, processing could include communicating with an upstream SOAP node, which did not respond. The message could succeed if resent at a later point in time.

NOTE: The SOAP 1.1 "Server" fault code is renamed "Receiver" in SOAP 1.2.

Create a SOAP message that contains an attachment.

The SOAP with Attachments API for Java (SAAJ) provides a standard way to send XML documents over the Internet from the Java platform. It is based on the SOAP 1.1 and SOAP with Attachments specifications, which define a basic framework for exchanging XML messages.

The process of creation and sending SOAP message includes following steps:

• Creating a SOAP connection.

• Creating a SOAP message.

• Populating the message.

• Sending the message.

• Retrieving the reply.

A SAAJ client is a standalone client. That is, it sends point-to-point messages directly to a Web Service that is implemented for request-response messaging. Request-response messaging is synchronous, meaning that a request is sent and its response is received in the same

operation. A request-response message is sent over a SOAPConnection object via the

method SOAPConnection.call, which sends the message and blocks until it receives a response. A standalone client can operate only in a client role, that is, it can only send requests and receive their responses.

A SOAPMessage object represents an XML document that is a SOAP message. A SOAPMessage object always has a required

SOAP part, and it may also have one or more attachment parts. The SOAP part must always have a SOAPEnvelope object, which

must in turn always contain a SOAPBody object. TheSOAPEnvelope object may also contain a SOAPHeader object, to which one or more headers can be added.

The SOAPBody object can hold XML fragments as the content of the message being sent. If you want to send content that is not in XML format or that is an entire XML document, your message will need to contain an attachment part in addition to the SOAP part. There is no limitation on the content in the attachment part, so it can include images or any other kind of content, including XML fragments and

documents. Common types of attachment include sound, picture, and movie data: .mp3, .jpg, and .mpg files.

The first thing a SAAJ client needs to do is get a connection in the form of a SOAPConnection object.

A SOAPConnection object is a point-to-point connection that goes directly from the sender to the recipient. The connection is

created by a SOAPConnectionFactory object. A client obtains the default implementation

for SOAPConnectionFactory by calling the following line of code:

Page 35: Chapter

SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();

The client can use factory to create a SOAPConnection object.

SOAPConnection connection = factory.createConnection();

Messages, like connections, are created by a factory. To obtain a MessageFactory object, you get an instance of the default

implementation for theMessageFactory class. This instance can then be used to create a SOAPMessage object:

MessageFactory messageFactory = MessageFactory.newInstance(); SOAPMessage message = messageFactory.createMessage();

All of the SOAPMessage objects that messageFactory creates, including message in the previous line of code, will be SOAP

messages. This means that they will have no pre-defined headers. The new SOAPMessage object message automatically contains the

required elements SOAPPart, SOAPEnvelope, and SOAPBody, plus the optional element SOAPHeader (which is

included for convenience). The SOAPHeader and SOAPBody objects are initially empty, and the code below will illustrate some of

the typical ways to add content. Content can be added to the SOAPPart object, to one or more AttachmentPart objects, or to both parts of a message.

package javax.xml.soap; public abstract class SOAPPart implements org.w3c.dom.Document { public abstract SOAPEnvelope getEnvelope() throws SOAPException; ... }

As stated earlier, all messages have a SOAPPart object, which has a SOAPEnvelope object containing

a SOAPHeader object and a SOAPBody object.

package javax.xml.soap; public interface SOAPEnvelope extends SOAPElement { public abstract Name createName(String localName, String prefix, String uri) throws SOAPException; public abstract Name createName(String localName) throws SOAPException; public abstract SOAPHeader getHeader() throws SOAPException; public abstract SOAPHeader addHeader() throws SOAPException; public abstract SOAPBody getBody() throws SOAPException; public abstract SOAPBody addBody() throws SOAPException; }

One way to add content to the SOAP part of a message is to create a SOAPHeaderElement object or

a SOAPBodyElement object and add an XML fragment that you build with the

method SOAPElement.addTextNode. The first three lines of the following code fragment access the SOAPBody object

body, which is used to create a new SOAPBodyElement object and add it to body. The argument passed to

the createName method is a Name object identifying the SOAPBodyElementbeing added. The last line adds the XML

string passed to the method addTextNode:

SOAPPart soapPart = message.getSOAPPart(); SOAPEnvelope envelope = soapPart.getEnvelope(); SOAPBody body = envelope.getBody(); Name bodyName = envelope.createName("text", "i", "http://hotitems.com"); SOAPBodyElement bodyElement = body.addBodyElement(bodyName); bodyElement.addTextNode("some-xml-text");

The content that you have just added to your SOAPBody object will look like the following when it is sent over the wire:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Body> <i:text xmlns:i="http://hotitems.com"> some-xml-text

Page 36: Chapter

</i:text> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

Another way is to add content to the SOAPPart object by passing it a javax.xml.transform.Source object, which

may be a SAXSource, DOMSource, orStreamSource object. The Source object contains content for the SOAP part

of the message and also the information needed for it to act as source input. AStreamSource object will contain the content as an

XML document; the SAXSource or DOMSource object will contain content and instructions for transforming it into an XML document.

The following code fragments illustrates adding content as a DOMSource object. The first step is to get the SOAPPart object from

the SOAPMessage object. Next the code uses methods from the JAXP API to build the XML document to be added. It uses

a DocumentBuilderFactory object to get a DocumentBuilderobject. Then it parses the given file to produce the

document that will be used to initialize a new DOMSource object. Finally, the code passes

the DOMSourceobject domSource to the method SOAPPart.setContent:

SOAPPart soapPart = message.getSOAPPart(); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dbFactory.newDocumentBuilder(); Document document = builder.parse("file:///foo.bar/soap.xml"); DOMSource domSource = new DOMSource(document); soapPart.setContent(domSource);

This code would work equally well with a SAXSource or a StreamSource object.

You use the setContent method when you want to send an existing SOAP message. If you have an XML document that you want to

send as the content of a SOAP message, you use the addDocument method on the body of the message:

Page 37: Chapter

SOAPBodyElement docElement = body.addDocument(document);

This allows you to keep your application data in a document that is separate from the SOAP envelope unless and until it is time to send that data as a message.

A SOAPMessage object may have no attachment parts, but if it is to contain anything that is not in XML format, that content must be contained in an attachment part. There may be any number of attachment parts, and they may contain anything from plain text to image files. In the following code fragment, the content is an image in a JPEG file, whose URL is used to initialize

the javax.activation.DataHandler object handler. The Message object message creates

the AttachmentPart object attachPart, which is initialized with the data handler containing the URL for the image.

Finally, the messageadds attachPart to itself:

URL url = new URL("http://foo.bar/img.jpg"); DataHandler handler = new DataHandler(url); AttachmentPart attachPart = message.createAttachmentPart(handler); message.addAttachmentPart(attachPart);

A SOAPMessage object can also give content to an AttachmentPart object by passing an Object and its content type

to the method createAttachmentPart:

AttachmentPart attachPart = message.createAttachmentPart( "content-string", "text/plain"); message.addAttachmentPart(attachPart);

Once you have populated a SOAPMessage object, you are ready to send it. A client uses

the SOAPConnection method call to send a message. This method sends the message and then blocks until it gets back a

response. The arguments to the method call are the message being sent and a URL object that contains the URL specifying the endpoint of the receiver.

SOAPMessage response = soapConnection.call(message, endpoint);

The following example shows a SOAP 1.1 message with an attached facsimile image of the signed claim form (claim.tiff), also it

illustrates the use of thecid reference in the body of the SOAP 1.1 message:

MIME-Version: 1.0 Content-Type: Multipart/Related; boundary=MIME_boundary; type=text/xml; start="<[email protected]>" Content-Description: This is the optional message description. --MIME_boundary Content-Type: text/xml; charset=UTF-8 Content-Transfer-Encoding: 8bit Content-ID: <[email protected]> <?xml version='1.0' ?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Body> .. <theSignedForm href="cid:[email protected]"/> .. </SOAP-ENV:Body> </SOAP-ENV:Envelope> --MIME_boundary Content-Type: image/tiff Content-Transfer-Encoding: binary Content-ID: <[email protected]> d3d3Lm1hcmNoYWwuY29taesgfSEVFES45345sdvgfszd== --MIME_boundary--

NOTE: In this example the "Content-Type" header line has been continued across two lines so the example prints easily. SOAP message senders should send headers on a single long line.

Page 38: Chapter

NOTE: Associate the attachment to theSignedForm element by adding an href attribute. The attachment is referred to through

a cid (Content-ID) URL:

... <myElement href="cid:xxxx" /> ... --MIME_boundary Content-Type: image/tiff Content-Transfer-Encoding: binary Content-ID: <xxxx> ...

NOTE: Unlike SOAP 1.1 XML references, do not use '#' (pound sign) in href attribute value when you refer to attachment, also when you

refer to attachment you must prepend unique identifier with prefix 'cid:'.

The following listing illustrates the creation of the SOAP request. The request asks a server to resize an image. The procedure is as follows:

1. Create SOAP connection and SOAP message objects through factories. 2. Retrieve the message body from the message object (intermediary steps: retrieve the SOAP part and envelope). 3. Create a new XML element to represent the request.

4. Create the attachment and initialize it with a DataHandler object.

5. Create more elements to represent the two parameters (source and percent).

6. Associate the attachment to the first parameter by adding an href attribute. The attachment is referred to through

a cid (Content-ID) URI. 7. Set the value of the second parameter directly as text and call the service.

The service replies with the resized image, again as an attachment. To retrieve it, you can test for a SOAP fault (which indicates an error). If there are no faults, retrieve the attachment as a file and process it. Using SAAJ API:

// Using SAAJ public File resize(String endPoint,File file) { SOAPConnection connection = SOAPConnectionFactory.newInstance().createConnection(); SOAPMessage message = MessageFactory.newInstance().createMessage(); SOAPPart part = message.getSOAPPart(); SOAPEnvelope envelope = part.getEnvelope(); SOAPBody body = envelope.getBody(); SOAPBodyElement operation = body.addBodyElement( envelope.createName("resize", "ps", "http://example.com")); DataHandler dh = new DataHandler(new FileDataSource(file)); AttachmentPart attachment = message.createAttachmentPart(dh); SOAPElement source = operation.addChildElement("source",""), SOAPElement percent = operation.addChildElement("percent",""); message.addAttachmentPart(attachment); source.addAttribute(envelope.createName("href"), "cid:" + attachment.getContentId()); percent.addTextNode("20"); SOAPMessage result = connection.call(message,endPoint); part = result.getSOAPPart(); envelope = part.getEnvelope(); body = envelope.getBody(); if(!body.hasFault()) { Iterator iterator = result.getAttachments(); if(iterator.hasNext()) { dh = ((AttachmentPart)iterator.next()).getDataHandler(); String fname = dh.getName(); if (null != fname) return new File(fname); } } return null; }

The code above will produce following SOAP 1.1 message with attachment:

POST /ws/resize HTTP/1.0 Content-Type: multipart/related; type="text/xml"; start="<EB6FC7EDE9EF4E510F641C481A9FF1F3>"; boundary="----=_Part_0_7145370.1075485514903" Accept: application/soap+xml, multipart/related, text/* Host: example.com:8080

Page 39: Chapter

SOAPAction: "" Content-Length: 1506005 ------=_Part_0_7145370.1075485514903 Content-Type: text/xml; charset=UTF-8 Content-Transfer-Encoding: binary Content-Id: <EB6FC7EDE9EF4E510F641C481A9FF1F3> <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <ps:resize xmlns:ps="http://example.com"> <source href="cid:E1A97E9D40359F85CA19D1B8A7C52AA3"/> <percent>20</percent> </ps:resize> </soapenv:Body> </soapenv:Envelope> ------=_Part_0_7145370.1075485514903 Content-Type: image/jpeg Content-Transfer-Encoding: binary Content-Id: <E1A97E9D40359F85CA19D1B8A7C52AA3> d3d3Lm1hcmNoYWwuY29taesgfSEVFES45345sdvgfszd== ------=_Part_0_7145370.1075485514903--

Chapter 3. Describing and Publishing (WSDL and UDDI)

Explain the use of WSDL in Web services, including a description of WSDL's basic elements, binding mechanisms and the basic WSDL operation types as limited by the WS-I Basic Profile 1.1.

• [WS-I_BP_1.1] Basic Profile Version 1.1

Warning

While SCDJWS 5.0 objectives specify WSDL 2.0 specification version, the exam questions are still based on the WSDL 1.1 specification.

WSDL is an XML-based language that allows formal XML desriptions of the interfaces of Web services:

• Interface information describing all publicly available functions.

• Data type information for all message requests and message responses.

• Binding information about the transport protocol to be used.

• Address information for locating the specified service.

WSDL benefits:

• It is an interface description is a contract between the server developers and the client developers (like Java interface represents a contract between client code and the actual Java object).

• It has formal descriptions which allows tool support, e.g. code template generators, integrate new services with little or no manual code.

WSDL language can be described as having two layers:

1. The service definition layer describes abstract properties:

• data types

• message types

• operations

Page 40: Chapter

• services 2. The binding layer describes concrete properties:

• protocols

• data formats

The definitions element MUST be the root element of all WSDL documents. It defines the name of the web service, declares

multiple namespaces used throughout the remainder of the document. An actual WSDL document consists of a set of definitions of the following kinds:

• types - Contains XML Schema element and type definitions. The types element describes all the data types used between the client and server. WSDL is not tied exclusively to a specific typing system, but it uses the W3C XML Schema specification as

its default choice. If the service uses only XML Schema built-in simple types, such as strings and integers, the types element is not required.

The types element encloses data type definitions that are relevant for the exchanged messages. For maximum interoperability and platform neutrality, WSDL prefers the use of XSD as the canonical type system, and treats it as the intrinsic type system.

<definitions .... > <types> <xsd:schema .... />* </types> </definitions>

The XSD type system can be used to define the types in a message regardless of whether or not the resulting wire format is actually XML, or whether the resulting XSD schema validates the particular wire format. This is especially interesting if there will be multiple bindings for the same message, or if there is only one binding but that binding type does not already have a type system in widespread use.

WS-I BP 1.1: A DESCRIPTION MUST NOT use QName references to WSDL components in namespaces that have been neither imported, nor defined in the referring WSDL document.

WS-I BP 1.1: A QName reference to a Schema component in a DESCRIPTION MUST use the namespace defined in

the targetNamespace attribute on the xsd:schema element, or to a namespace defined in

the namespace attribute on an xsd:import element within the xsd:schema element.

WS-I BP 1.1: All xsd:schema elements contained in a wsdl:types element of a DESCRIPTION MUST have

a targetNamespace attribute with a valid and non-null value, UNLESS the xsd:schema element

has xsd:import and/or xsd:annotation as its only child element(s).

WS-I BP 1.1: In a DESCRIPTION, declarations MUST NOT extend or restrict the soapenc:Array type.

WS-I BP 1.1: In a DESCRIPTION, declarations MUST NOT use wsdl:arrayType attribute in the type declaration.

WS-I BP 1.1: In a DESCRIPTION, elements SHOULD NOT be named using the convention ArrayOfXXX.

WS-I BP 1.1: An ENVELOPE MUST NOT include the soapenc:arrayType attribute.

CORRECT:

Given the WSDL Description:

<xsd:element name="MyArray1" type="tns:MyArray1Type"/> <xsd:complexType name="MyArray1Type"> <xsd:sequence> <xsd:element name="x" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType>

Page 41: Chapter

The envelope would serialize as (omitting namespace declarations for clarity):

<MyArray1> <x>abcd</x> <x>efgh</x> </MyArray1>

INCORRECT (uses soapenc:arrayType attribute and soapenc:Array type):

Given the WSDL Description:

<xsd:element name="MyArray2" type="tns:MyArray2Type"/> <xsd:complexType name="MyArray2Type" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" > <xsd:complexContent> <xsd:restriction base="soapenc:Array"> <xsd:sequence> <xsd:element name="x" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> <xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="tns:MyArray2Type[]"/> </xsd:restriction> </xsd:complexContent> </xsd:complexType>

The envelope would serialize as (omitting namespace declarations for clarity):

<MyArray2 soapenc:arrayType="tns:MyArray2Type[]" > <x>abcd</x> <x>efgh</x> </MyArray2>

• message - Consists of either a number of named parts typed by XML Schema elements, or a single part typed by a

XML Schema type. The messageelement describes a one-way message, whether it is a single message request or a single

message response. It defines the name of the message and contains zero or more message part elements, which can refer to message parameters or message return values.

• portType - describing a set of operations, each being either:

o one-way: The endpoint receives an input message. (NOTE: The WS-I BP 1.1 restricts the

valid wsdl:operations to one-way and request-response operations):

A DESCRIPTION MUST NOT use Solicit-Response and Notification type operations in

a wsdl:portType definition.

<wsdl:definitions .... > <wsdl:portType .... > * <wsdl:operation name="nmtoken"> <wsdl:input name="nmtoken"? message="qname"/> </wsdl:operation> </wsdl:portType > </wsdl:definitions>

Page 42: Chapter

o request-response: The endpoint receives an input message and then responds with an output message (like

RPC - Remote Procedure Call). (NOTE: The WS-I BP 1.1 restricts the valid wsdl:operations to one-way and request-response operations).

o

o <wsdl:definitions .... >

o <wsdl:portType .... > *

o <wsdl:operation name="nmtoken" parameterOrder="nmtokens">

o <wsdl:input name="nmtoken"? message="qname"/>

o <wsdl:output name="nmtoken"? message="qname"/>

o <wsdl:fault name="nmtoken" message="qname"/>*

o </wsdl:operation>

o </wsdl:portType >

o </wsdl:definitions>

o

o solicit-response: The endpoint sends an output message and then receives an input message (NOTE: A

DESCRIPTION MUST NOT use Solicit-Response and Notification type operations in

a wsdl:portType definition - R2303 - BP 1.1).

o

o <wsdl:definitions .... >

o <wsdl:portType .... > *

o <wsdl:operation name="nmtoken" parameterOrder="nmtokens">

o <wsdl:output name="nmtoken"? message="qname"/>

o <wsdl:input name="nmtoken"? message="qname"/>

o <wsdl:fault name="nmtoken" message="qname"/>*

o </wsdl:operation>

o </wsdl:portType >

o </wsdl:definitions>

o

o notification: The endpoint sends an output message (NOTE: A DESCRIPTION MUST NOT use Solicit-Response and Notification type operations in a wsdl:portType definition - R2303 - BP 1.1).

o

o <wsdl:definitions .... >

o <wsdl:portType .... > *

o <wsdl:operation name="nmtoken" parameterOrder="nmtokens">

o <wsdl:output name="nmtoken"? message="qname"/>

o </wsdl:operation>

o </wsdl:portType >

o </wsdl:definitions>

o

• The portType element combines multiple message elements to form a complete one-way or round-trip operation. For

example, a portType can combine one request and one response message into a single request/response operation, most

commonly used in SOAP services. Note that a portType can (and frequently does) define multiple operations.

• binding - Selects communication protocol and data formats for each operation and message.

The binding element describes the concrete specifics of how the service will be implemented on the wire. WSDL includes built-in extensions for defining SOAP services, and SOAP-specific information therefore goes here.

NOTE: For interoperability the WS-I BP 1.1 requires that all messages must be sent using the SOAP 1.1 protocol over an HTTP transport:

Page 43: Chapter

WS-I BP 1.1: A wsdl:binding element in a DESCRIPTION MUST use WSDL SOAP Binding as defined in WSDL 1.1 Section 3.

WS-I BP 1.1: A wsdl:binding element in a DESCRIPTION MUST specify the HTTP transport protocol with SOAP binding.

Specifically, the transportattribute of its soapbind:binding child MUST have the

value "http://schemas.xmlsoap.org/soap/http".

The SOAP messages must be in either "document-literal" or "rpc-literal" form:

WS-I BP 1.1: A wsdl:binding in a DESCRIPTION MUST either be a rpc- literal binding or a document-literal binding.

The WS-I BP 1.1 requires that a wsdl:binding and its wsdl:portType have the same list

of wsdl:operations. A perfect matching between the two lists is established through a 1-1 and onto relation from

the wsdl:binding to the wsdl:portType. The wsdl:binding should completely bind all operations

within a wsdl:portType:

WS-I BP 1.1: A wsdl:binding in a DESCRIPTION MUST have the same set of wsdl:operations as

the wsdl:portType to which it refers.

• service - Describes a collection of named ports, each associated with a binding and a network address.

The service element defines the address for invoking the specified service. Most commonly, this includes a URL for invoking the SOAP service.

The simplified structure of a WSDL document is:

<definitions> <!-- root WSDL element --> <types> <!-- defines data types to be transmitted --> </types> <message> <!-- defines messages to be transmitted --> </message> <portType> <!-- defines operations (functions) to be supported --> </portType> <binding> <!-- defines how will the messages be transmitted on the wire --> </binding> <service> <!-- defines location of web service --> </service> </definitions>

WSDL document grammar:

<wsdl:definitions name="nmtoken"? targetNamespace="uri"?> <import namespace="uri" location="uri"/>* <wsdl:documentation .... /> ? <wsdl:types> ? <wsdl:documentation .... />? <xsd:schema .... />* <-- extensibility element --> * </wsdl:types> <wsdl:message name="nmtoken"> * <wsdl:documentation .... />? <part name="nmtoken" element="qname"? type="qname"?/> *

Page 44: Chapter

</wsdl:message> <wsdl:portType name="nmtoken">* <wsdl:documentation .... />? <wsdl:operation name="nmtoken">* <wsdl:documentation .... /> ? <wsdl:input name="nmtoken"? message="qname">? <wsdl:documentation .... /> ? </wsdl:input> <wsdl:output name="nmtoken"? message="qname">? <wsdl:documentation .... /> ? </wsdl:output> <wsdl:fault name="nmtoken" message="qname"> * <wsdl:documentation .... /> ? </wsdl:fault> </wsdl:operation> </wsdl:portType> <wsdl:binding name="nmtoken" type="qname">* <wsdl:documentation .... />? <-- extensibility element --> * <wsdl:operation name="nmtoken">* <wsdl:documentation .... /> ? <-- extensibility element --> * <wsdl:input> ? <wsdl:documentation .... /> ? <-- extensibility element --> </wsdl:input> <wsdl:output> ? <wsdl:documentation .... /> ? <-- extensibility element --> * </wsdl:output> <wsdl:fault name="nmtoken"> * <wsdl:documentation .... /> ? <-- extensibility element --> * </wsdl:fault> </wsdl:operation> </wsdl:binding> <wsdl:service name="nmtoken"> * <wsdl:documentation .... />? <wsdl:port name="nmtoken" binding="qname"> * <wsdl:documentation .... /> ? <-- extensibility element --> </wsdl:port> <-- extensibility element --> </wsdl:service> <-- extensibility element --> * </wsdl:definitions>

Example of simple WSDL (SOAP 1.1 Request-Response via HTTP):

<?xml version="1.0" encoding="UTF-8"?> <definitions name="StockQuote" targetNamespace="http://example.com/stockquote.wsdl" xmlns:tns="http://example.com/stockquote.wsdl" xmlns:xsd1="http://example.com/stockquote.xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns="http://schemas.xmlsoap.org/wsdl/"> <types> <schema targetNamespace="http://example.com/stockquote.xsd" xmlns="http://www.w3.org/2000/10/XMLSchema"> <element name="TradePriceRequest"> <complexType> <all> <element name="tickerSymbol" type="string"/> </all> </complexType> </element> <element name="TradePrice"> <complexType> <all> <element name="price" type="float"/> </all> </complexType> </element>

Page 45: Chapter

</schema> </types> <message name="GetLastTradePriceInput"> <part name="body" element="xsd1:TradePriceRequest"/> </message> <message name="GetLastTradePriceOutput"> <part name="body" element="xsd1:TradePrice"/> </message> <portType name="StockQuotePortType"> <operation name="GetLastTradePrice"> <input message="tns:GetLastTradePriceInput"/> <output message="tns:GetLastTradePriceOutput"/> </operation> </portType> <binding name="StockQuoteSoapBinding" type="tns:StockQuotePortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="GetLastTradePrice"> <soap:operation soapAction="http://example.com/GetLastTradePrice"/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding> <service name="StockQuoteService"> <documentation>My first service</documentation> <port name="StockQuotePort" binding="tns:StockQuoteBinding"> <soap:address location="http://example.com/stockquote"/> </port> </service> </definitions>

Describe how WSDL enables one to separate the description of the abstract functionality offered by a service from concrete details of a service description such as "how" and "where" that functionality is offered.

• [WS-I_BP_1.1] Basic Profile Version 1.1

Warning

While SCDJWS 5.0 objectives specify WSDL 2.0 specification version, the exam questions are still based on the WSDL 1.1 specification.

A WSDL document defines services as collections of network endpoints, or ports. In WSDL, the abstract definitions of endpoints and messages are separated from their concrete network deployment or data format bindings. This separation supports the reuse of abstract definitions: messages, which are abstract descriptions of exchanged data, and port types, which are abstract collections of operations. The concrete protocol and data format specifications for a particular port type constitutes a reusable binding. A port is defined by associating a network address with a reusable binding, and a collection of ports defines a service. Therefore, a WSDL document is composed of several elements.

The following is the structure of the information in a WSDL file:

Page 46: Chapter

A WSDL file contains the following parts:

• Web service interface definition (Abstract part)

This part contains the elements and the namespaces.

Describes the messages it sends and receives.

Describes the operation associates a message exchange pattern with one or more messages.

• Web service implementation (Concrete part)

This part contains the definition of the service and ports.

Specifies transport and wire format details for one or more interfaces.

Specifies a port (an endpoint) associates a network address with a binding.

Specifies a service which groups together endpoints that implement a common interface.

Page 47: Chapter

A WSDL file describes a Web Service with the following elements:

• portType

The description of the operations and associated messages (interface). The portType element defines abstract operations:

o One-way

The operation can receive a message but will not return a response.

o Request-response

The operation can receive a request and will return a response.

o Solicit-response

The operation can send a request and will wait for a response.

o Notification

The operation can send a message but will not wait for a response.

<portType name="procurementPortType"> <operation name="orderGoods"> <input message = "OrderMsg"/> </operation> </portType>

• message

The description of input and output parameters and return values.

Page 48: Chapter

<message name="OrderMsg"> <part name="productName" type="xs:string"/> <part name="quantity" type="xs:integer"/> </message>

• types

The schema for describing XML types used in the messages.

• binding

The bindings describe the protocol that is used to access a portType, as well as the data formats for the messages that are

defined by a particularportType element.

binding attributes are:

o name any name

o type - points to the port type defined in the abstract part

soap:binding attributes are:

o style - "rpc" | "document"

o transport - Communication protocol : SOAP, Transport protocol : HTTP/SMTP

operation element:

o defines each operation that the port exposes.

o must also specify how the input and output are encoded : literal | encoded

<binding name="ProcurementSoapBinding" type="tns:procurementPortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="orderGoods"> <soap:operation soapAction="http://example.com/orderGoods"/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding>

• service

The services and ports define the location of the Web Service.

The service contains the Web Service name and a list of ports.

<service name="ProcurementService"> <port name="ProcurementPort" binding="tns:ProcurementSoapBinding"> <soap:address location="http://example.com/procurement"/> </port> </service>

Page 49: Chapter

• port

The port contain the location of the Web Service and the binding used for service access.

<port name="ProcurementPort" binding="tns:ProcurementSoapBinding"> <soap:address location="http://example.com/procurement"/> </port>

Describe the Component Model of WSDL including Descriptions, Interfaces, Bindings, Services and Endpoints.

• [NONE] blah

WSDL 2.0 Conceptual Model

The description of a web service can be modeled in two parts. In the abstract part, WSDL describes a web service in terms of messages it sends and receives through a type system, typically W3C XML Schema. Message exchange patterns define the sequence and cardinality of

messages. An operationassociates message exchange patterns with one or more messages. An interface groups these operations in a transport and wire independent manner.

In the concrete part of the description, bindings specify the transport and wire format for interfaces. A

service endpoint associates network address with a binding. Finally, a service groups the endpoints that implement a common interface. Figure below shows the conceptual WSDL component model:

Description

This component serves as the root container for other components, most notably interfaces, bindings, and services. Abstract and concrete components are distinctly identified and separated. The service interfaces compose the abstract elements of the document with their respective messages and operations. The binding, service, and endpoints compose the concrete elements of the document.

Page 50: Chapter

Interface

This component serves as a container for operations, which in turn serves as a container for messages. The importance of this feature arises from the inclusion of Message Exchange Patterns (MEPs), since an operation can consist of more than simple request and response messages.

One of the most discussed features of WSDL 2.0 in the industry is the ability for interfaces to extend one another. This inclusion as a feature, along with the ability to include and import WSDL, certainly makes the job of tool developers more difficult. Yet interface inheritance should increase the reusability of interfaces across an organization.

An interface element encloses a named set of abstract operations and the abstract messages. It can optionally extend one or more

other interfaces. Interfaces are referred to by QName in other components such as bindings. The interface operation element has name and pattern as required attributes, while style is an optional attribute. Features defines functionalities associated with the message exchanges between communicating parties, which might include reliability, security, correlation, and routing. Property is used to control the behavior of a feature. It has a set of possible and permissible values specified by references to a schema description. These values can be shared among features.

Binding

This component represents the detailed information required to access an endpoint. The binding provides the glue the makes the whole system work and provides mechanisms for defining concrete formats for faults and messages and protocol interactions for interface operations.

The binding element defines the underlying transport and wire format for messages. Each binding in the WSDL references to

an interface. All operations defined within the interface must be bound in the binding. An endpoint in the service component references a binding. Both endpoints and bindings are modeled to support flexibility and location transparency. Multiple endpoints with different network address can still share the same protocol binding. WSDL 2.0 Bindings specification defines binding extensions for protocols and message formats such as SOAP, HTTP and MIME.

Page 51: Chapter

Service

This component represents the collection of endpoints where the service may be invoked.

Initial thoughts may envision that the Service component contains the bulk of the specification. However, it mainly serves to tie the service interface to one or many endpoints implementing that interface.

A service element describes a set of endpoints which refer to a single network address for a binding. All other protocol specific

information is contained in the binding. Service can be referred by QName. service element has

a name and interface which are required attributes.

Endpoint

This component represents a collection of information for a given service implementation. The endpoint ties a specific binding to the specific address so the service can be invoked.

Describe the basic functions provided by the UDDI Publish and Inquiry APIs to interact with a UDDI business registry.

Two types of UDDI APIs are defined. A publisher's API is provided for interactions between programs and the UDDI registry for the purpose of storing or changing data in the registry. An inquiry API is provided for programs that want to access the registry to read information from the registry.

Authenticated access is required to use the publishers API. Each Operator Site is responsible for selecting and implementing an authentication protocol that is compatible with the publishers API, as well as providing a new user sign-up mechanism. Before using any of the publisher API functions, the caller is responsible for signing up with one or more Operator Sites or compatible registries and establishing user credentials.

The Inquiry and Publishers API functions are exposed as SOAP messages over HTTP. HTTPS (specifically SSL 3.0) is used for all publisher API calls in order to assure wire privacy. No authentication is required to make use of the Inquiry API functions.

SOAP is a method for using Extensible Markup Language (XML) in message and remote procedure call (RPC) based protocols. SOAP has been jointly defined and submitted to the World Wide Web consortium (W3C) as a note.

UDDI uses SOAP in conjunction with HTTP to provide a simple mechanism for passing XML messages to Operator Sites using a standard HTTP-POST protocol. Unless specified, all responses will be returned in the normal HTTP response document.

The general structure of a UDDI SOAP message:

POST /someVerbHere HTTP/1.1 Host: www.someoperator.org Content-Type: text/xml; charset="utf-8" Content-Length: nnnn SOAPAction: "" <?xml version="1.0" encoding="UTF-8" ?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <xxx_xxx_xxx generic="2.0" xmlns="urn:uddi-org:api_v2"> ... </xxx_xxx_xxx> </Body> </Envelope>

Inquiry API functions

The messages in this section represent inquiries that anyone can make of any UDDI Operator Site at any time. These messages all behave synchronously and are required to be exposed via HTTP-POST only. Other synchronous or asynchronous mechanisms may be provided at the discretion of the individual UDDI Operator Site or UDDI compatible registry.

The publicly accessible queries are:

Page 52: Chapter

• find_binding: Used to locate specific bindings within a registered businessService. Returns

a bindingDetail message.

• find_business: Used to locate information about one or more businesses. Returns a businessList message.

• find_relatedBusinesses: Used to locate information about businessEntity registrations that are related to a specific business entity whose key is passed in the inquiry. The Related Businesses feature is used to manage registration of business units and subsequently relate them based on organizational hierarchies or business partner relationships.

Returns a relatedBusinessesList message.

• find_service: Used to locate specific services within a registered businessEntity. Returns

a serviceList message.

• find_tModel: Used to locate one or more tModel information structures. Returns a tModelList structure.

• get_bindingDetail: Used to get full bindingTemplate information suitable for making one or more

service requests. Returns a bindingDetailmessage.

• get_businessDetail: Used to get the full businessEntity information for one or more businesses or

organizations. Returns a businessDetailmessage.

• get_businessDetailExt: Used to get extended businessEntity information. Returns

a businessDetailExt message.

• get_serviceDetail: Used to get full details for a given set of registered businessService data.

Returns a serviceDetail message.

• get_tModelDetail: Used to get full details for a given set of registered tModel data. Returns

a tModelDetail message.

Publish API functions

The messages in this section represent commands that require authenticated access to an UDDI Operator Site, and are used to publish and update information contained in a UDDI compatible registry. Each business should initially select one Operator Site to host their information. Once chosen, information can only be updated at the site originally selected. UDDI provides no automated means to reconcile multiple or duplicate registrations.

The messages defined in this section all behave synchronously and are callable via HTTP-POST only. HTTPS is used exclusively for all of the calls defined in this publisher's API. The publishing API calls defined that UDDI operators support are:

• add_publisherAssertions: Used to add relationship assertions to the existing set of assertions.

• delete_binding: Used to remove an existing bindingTemplate from

the bindingTemplates collection that is part of a specified businessServicestructure.

• delete_business: Used to delete registered businessEntity information from the registry.

• delete_publisherAssertions: Used to delete specific publisher assertions from the assertion collection controlled by a particular publisher account. Deleting assertions from the assertion collection will affect the visibility of business relationships. Deleting an assertion will cause any relationships based on that assertion to be invalidated.

• delete_service: Used to delete an existing businessService from

the businessServices collection that is part of a specified businessEntity.

• delete_tModel: Used to hide registered information about a tModel. Any tModel hidden in this way is still

usable for reference purposes and accessible via the get_tModelDetail message, but is simply hidden

from find_tModel result sets. There is no way to actually cause a tModel to be deleted, except by administrative petition.

• discard_authToken: Used to inform an Operator Site that a previously provided authentication token is no longer

valid and should be considered invalid if used after this message is received and until such time as an authToken value is

recycled or reactivated at an operator's discretion. Seeget_authToken.

• get_assertionStatusReport: Used to get a status report containing publisher assertions and status information. This report is useful to help an administrator manage active and tentative publisher assertions. Publisher assertions

are used in UDDI to manage publicly visible relationships between businessEntity structures. Relationships are a feature introduced in generic 2.0 that help manage complex business structures that require more than

one businessEntity or more than one publisher account to manage parts of a businessEntity. Returns

an assertionStatusReport that includes the status of all assertions made involving

any businessEntity controlled by the requesting publisher account.

• get_authToken: Used to request an authentication token from an Operator Site. Authentication tokens are required when using all other API's defined in the publishers API. This function serves as the program's equivalent of a login request.

Page 53: Chapter

• get_publisherAssertions: Used to get a list of active publisher assertions that are controlled by an individual

publisher account. Returns apublisherAssertions message containing all publisher assertions associated with a specific publisher account. Publisher assertions are used to control publicly visible business relationships.

• get_registeredInfo: Used to request an abbreviated synopsis of all information currently managed by a given individual.

• save_binding: Used to register new bindingTemplate information or update

existing bindingTemplate information. Use this to control information about technical capabilities exposed by a registered business.

• save_business: Used to register new businessEntity information or update

existing businessEntity information. Use this to control the overall information about the entire business. Of

the save_xx API's this one has the broadest effect. In UDDI V2, a feature is introduced where save_businesscan

be used to reference a businessService that is parented by another businessEntity.

• save_service: Used to register or update complete information about a businessService exposed by a

specified businessEntity.

• save_tModel: Used to register or update complete information about a tModel.

• set_publisherAssertions: used to save the complete set of publisher assertions for an individual publisher account. Replaces any existing assertions, and causes any old assertions that are not reasserted to be removed from the registry. Publisher assertions are used to control publicly visible business relationships.

Chapter 4. JAX-WS

Explain JAX-WS technology for building web services and client that communicate using XML.

• [NONE] blah

Java API for XML-Based Web Services (JAX-WS) is the next generation Web services programming model complimenting the foundation provided by the Java API for XML-based RPC (JAX-RPC) programming model. Using JAX-WS, development of Web services and clients is simplified with more platform independence for Java applications by the use of dynamic proxies and Java annotations.

JAX-WS is a programming model that simplifies application development through support of a standard, annotation-based model to develop Web Service applications and clients. The JAX-WS technology strategically aligns itself with the current industry trend towards a more document-centric messaging model and replaces the remote procedure call programming model as defined by JAX-RPC. JAX-RPC has limitations and does not support various complex document-centric services. JAX-WS is the strategic programming model for developing Web services and is a required part of the Java Platform, Enterprise Edition 5 (Java EE 5). JAX-WS is also known as JSR 224.

The implementation of the JAX-WS programming standard provides the following enhancements for developing Web services and clients:

• Better platform independence for Java applications

Using JAX-WS APIs, development of Web services and clients is simplified with better platform independence for Java applications. JAX-WS takes advantage of the dynamic proxy mechanism to provide a formal delegation model with a pluggable provider. This is an enhancement over JAX-RPC, which relies on the generation of vendor-specific stubs for invocation.

• Annotations

JAX-WS introduces support for annotating Java classes with metadata to indicate that the Java class is a Web service. JAX-WS supports the use of annotations based on the Metadata Facility for the Java Programming Language (JSR 175) specification, the Web Services Metadata for the Java Platform (JSR 181) specification and annotations defined by the JAX-WS 2.1 specification. Using annotations within the Java source and within the Java class simplifies development of Web services. Use annotations to define information that is typically specified in deployment descriptor files, WSDL files, or mapping metadata from XML and WSDL files into the source artifacts.

For example, you can embed a simple @WebService tag in the Java source to expose the bean as a Web service:

@WebService

Page 54: Chapter

public class QuoteBean implements StockQuote { public float getQuote(String sym) { ... } }

The @WebService annotation tells the server runtime environment to expose all public methods on that bean as a Web service. Additional levels of granularity can be controlled by adding additional annotations on individual methods or parameters. Using annotations makes it much easier to expose Java artifacts as Web services. In addition, as artifacts are created from using some of the top-down mapping tools starting from a WSDL file, annotations are included within the source and Java classes as a way of capturing the metadata along with the source files.

Using annotations also improves the development of Web services within a team structure because you do not need to define every Web service in a single or common deployment descriptor as required with JAX-RPC Web services. Taking advantage of annotations with JAX-WS Web services enables parallel development of the service and the required metadata.

For JAX-WS Web services, the use of the webservices.xml deployment descriptor is optional because you can use annotations to specify all of the information that is contained within the deployment descriptor file. You can use the deployment descriptor file to augment or override existing JAX-WS annotations. Any information that you define in

the webservices.xml deployment descriptor overrides any corresponding information that is specified by annotations.

For example, if your service implementation class for your JAX-WS Web service includes the following:

o the @WebService annotation:

o @WebService(wsdlLocation="http://myhost.com/ExampleService.wsdl")

o the webservices.xml file specifies a different file name for the WSDL document as follows:

o

o <webservices>

o <webservice-description>

o <webservice-description-name>ExampleService</webservice-description-name>

o <wsdl-file>META-INF/wsdl/ExampleService.wsdl</wsdl-file>

o ....

o </webservice-description>

o </webservices>

o

In this case, the value that is specified in the deployment descriptor, META-INF/wsdl/ExampleService.wsdl overrides the annotation value.

• Invoking Web services asynchronously

With JAX-WS, Web services are called both synchronously and asynchronously. JAX-WS adds support for both a polling and callback mechanism when calling Web services asynchronously. Using a polling model, a client can issue a request, get a response object back, which is polled to determine if the server has responded. When the server responds, the actual response is retrieved. Using the callback model, the client provides a callback handler to accept and process the inbound response object. Both the polling and callback models enable the client to focus on continuing to process work without waiting for a response to return, while providing for a more dynamic and efficient model to invoke Web services.

For example, a Web service interface might have methods for both synchronous and asynchronous requests. Asynchronous requests are identified in the following example:

@WebService public interface CreditRatingService { // sync operation Score getCreditScore(Customer customer); // async operation with polling Response<Score> getCreditScoreAsync(Customer customer);

Page 55: Chapter

// async operation with callback Future<?> getCreditScoreAsync(Customer customer, AsyncHandler<Score> handler); }

The asynchronous invocation that uses the callback mechanism requires an additional input by the client programmer. The callback is an object that contains the application code that is run when an asynchronous response is received. Use the following code example to invoke an asynchronous callback handler:

CreditRatingService svc = ...; Future<?> invocation = svc.getCreditScoreAsync(customer, new AsyncHandler<Score>() { public void handleResponse (Response<Score> response) { Score score = response.get(); // do work here... } } );

Use the following code example to invoke an asynchronous polling client:

CreditRatingService svc = ...; Response<Score> response = svc.getCreditScoreAsync(customer); while (!response.isDone()) { // Complete an action while we wait. } // No cast needed, because of generics. Score score = response.get();

• Using resource injection

JAX-WS supports resource injection to further simplify development of Web services. JAX-WS uses this key feature of Java EE 5 to shift the burden of creating and initializing common resources in a Java runtime environment from your Web service application to the application container environment, itself. JAX-WS provides support for a subset of annotations that are defined in JSR-250 for resource injection and application life cycle in its runtime environment.

The application server also supports the usage of the @Resource or @WebServiceRef annotation to declare JAX-WS managed clients and to request injection of JAX-WS services and ports. When either of these annotations are used on a field or method, they result in injection of a JAX-WS service or port instance. The usage of these annotations also results in the type specified by the annotation being bound into the JNDI namespace.

The @Resource annotation is defined by the JSR-250, Common Annotations specification that is included in Java Platform,

Enterprise Edition 5 (Java EE 5). By placing the @Resource annotation on a variable of

type javax.xml.ws.WebServiceContext within a service endpoint implementation class, you can request

a resource injection and collect the javax.xml.ws.WebServiceContext interface related to that particular

endpoint invocation. From theWebServiceContext interface, you can collect the MessageContext for the

request associated with the particular method call using thegetMessageContext() method.

The @WebServiceRef annotation is defined by the JAX-WS specification.

The following example illustrates using the @Resource and @WebServiceRef annotations for resource injection:

@WebService public class MyService { @Resource

Page 56: Chapter

private WebServiceContext ctx; @Resource private SampleService svc; @WebServiceRef private SamplePort port; public String echo (String input) { ... } }

• Data binding with JAXB 2.1

JAX-WS leverages the Java Architecture for XML Binding (JAXB) 2.1 API and tools as the binding technology for mappings between Java objects and XML documents. JAX-WS tooling relies on JAXB tooling for default data binding for two-way mappings between Java objects and XML documents. JAXB data binding replaces the data binding described by the JAX-RPC specification.

The JAXB 2.1 specification provides enhancements such as improved compilation support and introduces support for

the @XMLSeeAlso annotation. With the improved compilation support, you now have the flexibility to control the whether

a new schema file is generated when using the schemagenschema generator and you can configure the xjc schema compiler so that it does not automatically generate new classes for a particular schema. You can use

the @XMLSeeAlso annotation to ensure that JAXB is aware of all the classes included in an inheritance hierarchy for a service endpoint interface.

• Dynamic and static clients

The dynamic client API for JAX-WS is called the dispatch client (javax.xml.ws.Dispatch). The dispatch client is

an XML messaging oriented client. The data is sent in either PAYLOAD or MESSAGE mode.

When using the PAYLOAD mode, the dispatch client is only responsible for providing the contents of

the soap:Body and JAX-WS adds the soap:Envelopeand soap:Header elements.

When using the MESSAGE mode, the dispatch client is responsible for providing the entire SOAP envelope including

the soap:Envelope, soap:Header, and soap:Body elements. JAX-WS does not add anything additional to the message.

The dispatch client supports asynchronous invocations using a callback or polling mechanism.

The static client programming model for JAX-WS is the called the proxy client. The proxy client invokes a Web service based on a Service Endpoint interface (SEI), which must be provided.

• Support for MTOM

Using JAX-WS, you can send binary attachments such as images or files along with Web services requests. JAX-WS adds support for optimized transmission of binary data as specified by Message Transmission Optimization Mechanism (MTOM).

• Multiple data binding technologies

JAX-WS exposes the following binding technologies to the end user: XML Source, SOAP Attachments API for Java (SAAJ) 1.3, and Java Architecture for XML Binding (JAXB) 2.1.

XML Source enables a user to pass a javax.xml.transform.Source into the runtime environment which

represents the data in a Source object to be processed.

SAAJ 1.3 now has the ability to pass an entire SOAP document across the interface rather than just the payload itself. This action

is done by the client passing the SAAJ SOAPMessage object across the interface.

JAX-WS leverages the JAXB 2.1 support as the data binding technology of choice between Java and XML.

Page 57: Chapter

• Support for SOAP 1.2

Support for SOAP 1.2 has been added to JAX-WS 2.0.

JAX-WS supports both SOAP 1.1 and SOAP 1.2 so that you can send binary attachments such as images or files along with Web services requests. JAX-WS adds support for optimized transmission of binary data as specified by MTOM.

• Development tools

JAX-WS provides the wsgen and wsimport command-line tools for generating portable artifacts for JAX-WS Web services. When creating JAX-WS Web services, you can start with either a WSDL file or an implementation bean class.

If you start with an implementation bean class, use the wsgen command-line tool to generate all the Web services server artifacts, including a WSDL file if requested.

If you start with a WSDL file, use the wsimport command-line tool to generate all the Web services artifacts for either the server or the client. The wsimport command-line tool processes the WSDL file with schema definitions to generate the portable artifacts, which include the service class, the service endpoint interface class, and the JAXB 2.1 classes for the corresponding XML schema.

• Support for WS-Addressing (JAX-WS 2.1)

JAX-WS 2.1 integrates support for the WS-Addressing standard in to the API. The new API enables you to create, transmit and use endpoint references to target a specific Web service endpoint. You can also explicitly specify the action URIs associated with the Web Services Description Language (WSDL) operations of your Web service.

• Support for JAX-WS 2.1 features

JAX-WS 2.1 introduces the concept of features as a way to programmatically control certain functions or behaviors. There are

three standard features: the AddressingFeature, the MTOMFeature, and

the RespectBindingFeature.

The AddressingFeature is used to enable or disable support for the WS-Addressing Version 1.0 specification.

The MTOMFeature is used to enable or disable support for Message Transmission Optimized Mechanism (MTOM) when sending binary attachments.

The RespectBindingFeature is used to enable or disable support for wsdl:binding extensions. The application server supports an additional feature, the SubmissionAddressingFeature, which is used to enable or disable support for WS-Addressing Member Submission specification (prior to the WS-Addressing Version 1.0 level of specification).

Describe the Integrated Stack (I-Stack) which consist of JAX-WS, JAXB, StAX, SAAJ.

JAX-WS

JAX-WS stands for Java API for XML Web Services. JAX-WS is a technology for building web services and clients that communicate using XML. JAX-WS allows developers to write message-oriented as well as RPC-oriented web services.

In JAX-WS, a web service operation invocation is represented by an XML-based protocol such as SOAP. The SOAP specification defines the envelope structure, encoding rules, and conventions for representing web service invocations and responses. These calls and responses are transmitted as SOAP messages (XML files) over HTTP.

Although SOAP messages are complex, the JAX-WS API hides this complexity from the application developer. On the server side, the developer specifies the web service operations by defining methods in an interface written in the Java programming language. The developer also codes one or more classes that implement those methods. Client programs are also easy to code. A client creates a proxy (a local object representing the service) and then simply invokes methods on the proxy. With JAX-WS, the developer does not generate or parse SOAP messages. It is the JAX-WS runtime system that converts the API calls and responses to and from SOAP messages.

Page 58: Chapter

With JAX-WS, clients and web services have a big advantage: the platform independence of the Java programming language. In addition, JAX-WS is not restrictive: a JAX-WS client can access a web service that is not running on the Java platform, and vice versa. This flexibility is possible because JAX-WS uses technologies defined by the World Wide Web Consortium (W3C): HTTP, SOAP, and the Web Service Description Language (WSDL). WSDL specifies an XML format for describing a service as a set of endpoints operating on messages.

Describe and compare JAX-WS development approaches.

Prev Chapter 4. JAX-WS Next

Describe and compare JAX-WS development approaches.

• [JAVA_EE_5_TUTORIAL] The Java EE 5 Tutorial

Empty

Class

A Java class (not an interface) annotated with a javax.jws.WebService annotation can be used to define a Web service.

In order to allow for a separation between Web service interface and implementation, if the WebService annotation on the class under consideration has aendpointInterface element, then the interface referred by this element is for all purposes the SEI associated with the class.

Otherwise, the class implicitly defines a service endpoint interface (SEI) which comprises all of the public methods that satisfy one of the following conditions:

1. They are annotated with the javax.jws.WebMethod annotation with the exclude element set to false or missing (since false is the default for this annotation element).

2. They are NOT annotated with the javax.jws.WebMethod annotation but their declaring class has a javax.jws.WebService annotation.

For mapping purposes, this implicit SEI and its methods are considered to be annotated with the same Web service-related annotations that the original class and its methods have.

In pratice, in order to exclude a public method of a class annotated with WebService and not directly specifying a endpointInterface from the implicitly defined SEI, it is necessary to annotate the method with a WebMethod annotation with the exclude element set to true.

For mapping purposes, this class must be a top level class or a static inner class. As defined by JSR 181, a class annotated with javax.jws.WebService MUST HAVE a default public constructor.

Interface

A Java service endpoint interface (SEI) is mapped to a wsdl:portType element. The wsdl:portType element acts as a container for other WSDL elements that together form the WSDL description of the methods in the corresponding Java SEI. An SEI is a Java interface that meets all of the following criteria:

1. It MUST carry a javax.jws.WebService annotation 2. Any of its methods MAY carry a javax.jws.WebMethod annotation 3. javax.jws.WebMethod if used, MUST NOT have the exclude element set to true. 4. All method parameters and return types are compatible with the JAXB 2.0 Java to XML Schema mapping definition

Method

Each public method in a Java SEI is mapped to a wsdl:operation element in the corresponding wsdl:portType plus one or more wsdl:message elements.

Comparing JAX-WS and JAX-RPC SEI mapping

WSDL for a simple HelloWorld Web service:

Page 59: Chapter

<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions xmlns:tns="urn:helloWorld/sample/ibm/com" ...> <wsdl:types> <xsd:schema ...> <xsd:element name="hello"> <xsd:complexType> <xsd:sequence> <xsd:element name="name" nillable="true" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="helloResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="response" nillable="true" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> </wsdl:types> <wsdl:message name="helloRequestMsg"> <wsdl:part element="tns:hello" name="helloParameters" /> </wsdl:message> <wsdl:message name="helloResponseMsg"> <wsdl:part element="tns:helloResponse" name="helloResult" /> </wsdl:message> <wsdl:portType name="HelloWorld"> <wsdl:operation name="hello"> <wsdl:input message="tns:helloRequestMsg" name="helloRequest" /> <wsdl:output message="tns:helloResponseMsg" name="helloResponse" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="HelloWorldBinding" type="tns:HelloWorld"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="hello"> <soap:operation soapAction="urn:helloWorld/sample/ibm/com/hello" /> <wsdl:input name="helloRequest"> <soap:body use="literal" /> </wsdl:input> <wsdl:output name="helloResponse"> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="HelloWorldService"> <wsdl:port name="port" binding="tns:HelloWorldBinding"> <soap:address location="http://server.org/" /> </wsdl:port> </wsdl:service> </wsdl:definitions>

JAX-RPC HelloWorld SEI:

package com.ibm.samples; public interface HelloWorld extends java.rmi.Remote { ... }

JAX-WS HelloWorld SEI:

package com.ibm.samples.helloworld; import javax.jws.WebService; @WebService(name = "HelloWorld", targetNamespace = "urn:samples.ibm.com/HelloWorld") public interface HelloWorld { ... }

Page 60: Chapter

There are three differences here:

• Package: The target namespace is "urn:helloWorld/sample/ibm/com". Both mappings take the domain name-like string and reverse the order of the elements. JAX-RPC's mapping stops at the first slash. JAX-WS's mapping continues with the string, adding the information after the first slash. Both specifications allow for custom namespace-to-package mappings.

• Annotations: JAX-WS requires that all SEIs include the @WebService annotation. JAX-WS includes support for the annotations defined in JSR-181 Web Services Metadata.

• java.rmi.Remote: The JAX-RPC SEI extends the java.rmi.Remote interface. JAX-WS no longer requires this.

Although JAX-WS provides support for Web services that have an SEI, this is not mandatory for all services. With JAX-WS, a JavaBean can be deployed on its own as a Web service implementation, as opposed to JAX-RPC where the bean must include an SEI. JAX-WS services deployed without an SEI are considered to have an implicit SEI.

Comparing JAX-WS and JAX-RPC operation mapping

• Exploring the document/literal wrapped pattern

JAX-RPC complete HelloWorld SEI:

package com.ibm.samples; public interface HelloWorld extends java.rmi.Remote { public java.lang.String hello(java.lang.String name) throws java.rmi.RemoteException; }

JAX-WS complete HelloWorld SEI:

package com.ibm.samples.helloworld; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.xml.ws.RequestWrapper; import javax.xml.ws.ResponseWrapper; @WebService(name = "HelloWorld", targetNamespace = "urn:samples.ibm.com/HelloWorld") public interface HelloWorld { @WebMethod(action = "urn:samples.ibm.com/HelloWorld/hello") @WebResult(name = "response", targetNamespace = "") @RequestWrapper(localName = "hello", targetNamespace = "urn:samples.ibm.com/HelloWorld", className = "com.ibm.samples.helloworld.Hello") @ResponseWrapper(localName = "helloResponse", targetNamespace = "urn:samples.ibm.com/HelloWorld", className = "com.ibm.samples.helloworld.HelloResponse") public String hello( @WebParam(name = "name", targetNamespace = "") String name ); }

As you can see, the JAX-WS mapping again has a lot of annotations. Another difference is that the JAX-RPC method can throwjava.rmi.RemoteException while the JAX-WS method is not defined to do so.

• Exploring document/literal pattern

Both JAX-RPC and JAX-WS support mapping operations that are document/literal, but are not wrapped. To accomplish this with the HelloWorldsample, you would need to remove the wrapper elements that represent the operation name.

Document/literal WSDL:

Page 61: Chapter

<wsdl:types> <xsd:schema targetNamespace="urn:helloWorld/sample/ibm/com" xmlns:tns="urn:helloWorld/sample/ibm/com" ... > <xsd:element name="hello" type="xsd:string"/> <xsd:element name="helloResponse" type="xsd:string"/> </xsd:schema> </wsdl:types> <wsdl:message name="helloRequestMsg"> <wsdl:part element="tns:hello" name="helloParameters" /> </wsdl:message> <wsdl:message name="helloResponseMsg"> <wsdl:part element="tns:helloResponse" name="helloResult" /> </wsdl:message>

The only difference is the parameter name. As with the previous case, putting the annotations aside, there is no real difference between the JAX-RPC mapping and the JAX-WS mapping.

JAX-RPC document/literal mapping:

public interface HelloWorld extends java.rmi.Remote { public java.lang.String hello(java.lang.String helloParameters) throws java.rmi.RemoteException; }

JAX-WS document/literal mapping:

@WebService(name = "HelloWorld", targetNamespace = "urn:helloWorld/sample/ibm/com") @SOAPBinding(parameterStyle = ParameterStyle.BARE) public interface HelloWorld { @WebMethod(action = "urn:helloWorld/sample/ibm/com/hello") @WebResult(name = "helloResponse", targetNamespace = "urn:helloWorld/sample/ibm/com", partName = "helloResult") public String hello( @WebParam(name = "hello", targetNamespace = "urn:helloWorld/sample/ibm/com", partName = "helloParameters") String helloParameters ); }

Notice that for JAX-WS, you no longer see the @RequestWrapper and @ResponseWrapper annotations. Also note that a new annotation appears at the interface level as well, @SOAPBinding. This annotation provides information about the parameter style. If absent, the default value for theparameterStyle attribute is wrapped.

• Exploring the RPC/literal patterns

With an RPC/literal style WSDL, the parts are defined in terms of types rather than elements. Listing below contains the relevant WSDL differences.

RPC/literal WSDL changes:

<wsdl:types/> <wsdl:message name="helloRequestMsg"> <wsdl:part name="helloParameters" type="xsd:string"/> </wsdl:message> <wsdl:message name="helloResponseMsg"> <wsdl:part name="helloResult" type="xsd:string"/> </wsdl:message>

JAX-RPC RPC/literal mapping:

Page 62: Chapter

public interface HelloWorld extends java.rmi.Remote { public java.lang.String hello(java.lang.String helloParameters) throws java.rmi.RemoteException; }

JAX-WS RPC/Literal mapping:

@WebService(name = "HelloWorld", targetNamespace = "urn:helloWorld/sample/ibm/com") @SOAPBinding(style = Style.RPC) public interface HelloWorld { @WebMethod(action = "urn:helloWorld/sample/ibm/com/hello") @WebResult(name = "helloResult", partName = "helloResult") public String hello( @WebParam(name = "helloParameters", partName = "helloParameters") String helloParameters ); }

Comparing this JAX-WS interface to the previous, you see that the @SOAPBinding annotation remains, but now it is not used for the parameter style, but rather the WSDL style.

• Exploring the RPC/encoded patterns

There is no comparison for RPC/encoded style operations that can be made. JAX-WS does not support any mappings for WSDL documents that contain an encoded representation for the data. This comes from JAX-WS's compliance with WS-I's Basic Profile 1.1, which does not allow usage of encoded WSDL documents. There are good reasons to build an RPC/encoded Web service, in which case you should stick with the JAX-RPC mappings, but if you want to write interoperable Web services, you should not use RPC/encoded.

Considering other JAX-WS and JAX-RPC differences

A major difference in operation mapping for JAX-WS over JAX-RPC is the introduction of asynchronous operations. Any WSDL operation with a two-way message flow, or one where the client expects to receive a response, can be mapped to an asynchronous Java representation. There are two different mechanisms, asynchronous with a callback and asynchronous polling, that require two different mappings.

JAX-WS asynchronous callback:

@WebMethod(action = "urn:samples.ibm.com/HelloWorld/hello") @RequestWrapper(localName = "hello", targetNamespace = "urn:samples.ibm.com/HelloWorld", className = "com.ibm.samples.helloworld.Hello") @ResponseWrapper(localName = "helloResponse", targetNamespace = "urn:samples.ibm.com/HelloWorld", className = "com.ibm.samples.helloworld.HelloResponse") public Future<?> helloAsync( @WebParam(name = "name", targetNamespace = "") String name, @WebParam(name = "asyncHandler", targetNamespace = "") AsyncHandler<String> asyncHandler );

JAX-WS asynchronous polling:

@WebMethod(action = "urn:samples.ibm.com/HelloWorld/hello") @RequestWrapper(localName = "hello", targetNamespace = "urn:samples.ibm.com/HelloWorld", className = "com.ibm.samples.helloworld.Hello") @ResponseWrapper(localName = "helloResponse", targetNamespace = "urn:samples.ibm.com/HelloWorld", className = "com.ibm.samples.helloworld.HelloResponse") public Response<String> helloAsync( @WebParam(name = "name", targetNamespace = "") String name );

Page 63: Chapter

There is no asynchronous mapping for WSDL operations in JAX-RPC, so you do not have anything to make a comparison to here. One important note, however, is that the asynchronous mappings only apply to the client side. No such asynchronous mappings exist for service endpoints, only for clients.

Comparing IN/OUT parameters for JAX-WS and JAX-RPC

Both JAX-RPC and JAX-WS support parameters known as IN/OUT parameters. In this scenario, both JAX-RPC and JAX-WS map that parameter to a holder parameter, but the impact this has is different for each mapping.

A WSDL with an IN/OUT parameter:

<xsd:element name="hello"> <xsd:complexType> <xsd:sequence> <xsd:element name="name" nillable="true" type="xsd:string" /> <xsd:element name="inout" nillable="true" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="helloResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="response" nillable="true" type="xsd:string" /> <xsd:element name="inout" nillable="true" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element>

JAX-RPC SEI with IN/OUT parameters:

public interface HelloWorld extends java.rmi.Remote { public java.lang.String hello( java.lang.String name, javax.xml.rpc.holders.StringHolder inout ) throws java.rmi.RemoteException; }

JAX-WS SEI with IN/OUT parameters:

@WebService(name = "HelloWorld", targetNamespace = "urn:helloWorld/sample/ibm/com") public interface HelloWorld { @WebMethod(action = "urn:helloWorld/sample/ibm/com/hello") @RequestWrapper(localName = "hello", targetNamespace = "urn:helloWorld/sample/ibm/com", className = "helloworld.sample.ibm.com.Hello") @ResponseWrapper(localName = "helloResponse", targetNamespace = "urn:helloWorld/sample/ibm/com", className = "helloworld.sample.ibm.com.HelloResponse") public void hello( @WebParam(name = "name", targetNamespace = "") String name, @WebParam(name = "inout", targetNamespace = "", mode = Mode.INOUT) Holder<String> inout, @WebParam(name = "response", targetNamespace = "", mode = Mode.OUT) Holder<String> response ); }

For JAX-RPC, there are a set of classes defined by the specification as holder classes for known types. These include types like java.lang.String and other primitive types. For user defined types, JAX-RPC requires that custom holder classes be generated that can handle the user-defined types. JAX-WS, on the other hand, makes use of the Generics feature in Java 5 to provide a single class that can work for all types, including user-defined types.

Another interesting thing to note here is the difference in return types. Rather than keeping the return type as JAX-RPC does, JAX-WS makes the methodvoid and makes use of the holder for what was the return value. By rule in JAX-WS, when there is more than one parameter that can be considered an OUT parameter for an operation, the return type must be void, and all OUT parameters are mapped to holder types.

Page 64: Chapter

Describe the features of JAX-WS including the usage of Java Annotations.

• [JAX-WS_2.0_RI] JAX-WS Reference Implementation Project

Java API for XML-Based Web Services (JAX-WS) relies on the use of annotations to specify metadata associated with Web services implementations and to simplify the development of Web services. Annotations describe how a server-side service implementation is accessed as a Web service or how a client-side Java class accesses Web services.

The JAX-WS programming standard introduces support for annotating Java classes with metadata that is used to define a service endpoint application as a Web service and how a client can access the Web service. JAX-WS supports the use of annotations based on the Metadata Facility for the Java Programming Language (JSR 175) specification, the Web Services Metadata for the Java Platform (JSR 181) specification and annotations defined by the JAX-WS 2.0 and later (JSR 224) specification which includes JAXB annotations. Using annotations from the JSR 181 standard, you can simply annotate the service implementation class or the service interface and now the application is enabled as a Web service. Using annotations within the Java source simplifies development and deployment of Web services by defining some of the additional information that is typically obtained from deployment descriptor files, WSDL files, or mapping metadata from XML and WSDL into the source artifacts.

Use annotations to configure bindings, handler chains, set names of portType, service and other WSDL parameters. Annotations are used in mapping Java to WSDL and schema, and at runtime to control how the JAX-WS runtime processes and responds to Web service invocations.

For JAX-WS Web services, the use of the webservices.xml deployment descriptor is OPTIONAL because you can use annotations to specify all of the information that is contained within the deployment descriptor file. You can use the deployment descriptor file to augment

or override existing JAX-WS annotations. Any information that you define in the webservices.xml deployment descriptor overrides any corresponding information that is specified by annotations.

JSR 181 (Web Services Metadata) Annotations

• javax.jws.WebService

The purpose of this annotation is to mark a endpoint implementation as implementing a web service or to mark that a service endpoint interface as defining a web service interface. All endpoint implementation classes MUST have

a WebService annotation and must meet the requirements of section 3.3 of the JAX-WS 2.0 specification.

Table 4.1. javax.jws.WebService

Property Description Default

name The name of

the wsdl:portType The unqualified name of the Java class or interface

targetNamespace

The XML namespace of the the WSDL and some of the XML elements generated from this web service. Most of the XML elements will be in the namespace according to the JAXB mapping rules.

The namespace mapped from the package name containing the web service according to section 3.2 of the JAX-WS 2.0 specification.

serviceName The Service name of the web

service: wsdl:service

The unqualified name of the Java class or interface

+"Service"

endpointInterface

The qualified name of the service endpoint interface. This annotation allows the separation of interface contract from implementation. If this property is specified, all

other WebService properties are

ignored as are all other 181 annotations. Only the annotations on the service endpoint interface will be taken into consideration. The endpoint implementation class is not required to implement

the endpointInterface.

None – If not specified, the endpoint implementation class is used to generate the web service contract. In this case, a service endpoint interface is not required.

portName The wsdl:portName The WebService.name + "Port"

Page 65: Chapter

Property Description Default

wsdlLocation Specifies the Web address of the WSDL document defining the Web service. The Web address is either relative or absolute.

-

Example 1:

@WebService(name="AddNumbers", targetNamespace="http://duke.example.org", name="AddNumbers") public class AddNumbersImpl { public int addNumbers(int number1, int number2) { return number1 + number2; } }

You can notice that the AddNumbersImpl implementation class does not implement a service endpoint interface. In JAX-WS 2.0 service endpoint interface is no longer required. If a service endpoint interfaces is desired, then

the @WebService annotation on the endpoint implementation is modified to specify the endpoint interface and the actual

service endpoint interface must also have a @WebService annotation. The following is the

above AddNumbersImpl modified to use a service endpoint interface.

Example 2:

@WebService(endpointInterface = "com.example.AddNumbersIF") public class AddNumbersImpl { public int addNumbers(int number1, int number2) { return number1 + number2; } } @WebService(targetNamespace="http://duke.example.org", name="AddNumbers") public interface AddNumbersIF { public int addNumbers(int number1, int number2); }

NOTE: The following rules apply for methods on classes annotated with the @WebService annotation:

o If the @WebService annotation of an implementation class references an Service Endpoint Interface (SEI), the

implementation class MUST NOT have any @WebMethod annotations.

o ALL public methods for an SEI are considered exposed methods regardless of whether

the @WebMethod annotation is specified or not. It is incorrect to have an @WebMethod annotation on an

SEI that contains the exclude attribute.

o For an implementation class that DOES NOT reference an SEI, if the @WebMethod annotation is specified with a

value of exclude=true, that method is NOT exposed. If the @WebMethod annotation is not specified, all public methods are exposed including the inherited methods with the exception of methods inherited

from java.lang.Object.

• javax.jws.WebMethod

The purpose of this annotation is to expose a method as a web service operation. The method must meet all the requirements of section 3.4 of the JAX-WS 2.0 specification.

Table 4.2. javax.jws.WebMethod

Property Description Default

operationName The name of the wsdl:operation matching this method. For operations using the mode The name of the

Page 66: Chapter

Property Description Default

defined

bySOAPBinding.Style.DOCUMENT,SOAPBinding.Use.LITERAL,

andSOAPBinding.ParameterStyle.BARE, this name is also used for the global

XML element representing the operations body element. The namespace of this name is taken from the

value WebService.targetNamespace or its default value.

Java method

action The XML namespace of the the WSDL and some of the XML elements generated from this web service. Most of the XML elements will be in the namespace according to the JAXB mapping rules.

""

exclude Used to exclude a method from the WebService. false

Example:

@WebService(targetNamespace="http://duke.example.org", name="AddNumbers") public interface AddNumbersIF { @WebMethod(operationName="add", action="urn:addNumbers") public int addNumbers(int number1, int number2); }

NOTE: Apply this annotation to methods on a client or server Service Endpoint Interface (SEI) or a server endpoint implementation class.

NOTE: The @WebMethod annotation is only supported on classes that are annotated with

the @WebService annotation.

• javax.jws.OneWay

The purpose of this annotation is to mark a method as a web service one-way operation. The method must meet all the requirements of section 3.4.1 of the JSR 224 spec.

Example:

@WebService(name="CheckIn") public interface CheckInIF { @WebMethod @OneWay public void checkIn(String name); }

• javax.jws.WebParam

This annotation is used to customize the mapping of a single parameter to a message part or element.

Table 4.3. javax.jws.WebParam

Property Description Default

name

Name of the parameter.

If the operation is rpc style

and @WebParam.partNamehas not been

specified, this is name of the wsdl:partrepresenting

the parameter.

@WebMethod.operationName, if the

operation isdocument style and the parameter style

@WebMethod.operationName,

if the operation isdocument style and the

parameter style is BARE. Otherwise, the default

is argN, where N represents the index of the

parameter in the method signature (starting

at arg0).

Page 67: Chapter

Property Description Default

is BARE.

If the operation is document style or the parameter

maps to a header, this is the local name of the XML element representing the parameter.

A name MUST be specified if the operation

is documentstyle, the parameter style is BARE, and

the mode is OUTor INOUT.

targetNamespace - -

mode

Represents the direction the parameter flows for this method. Possible values

are IN, INOUT and OUT. INOUTand OUT modes

can only be used with parameters that meet the requirements for a holder as classified by section 3.5 of the JAX-WS 2.0

specification. OUT andINOUT parameters can be used

by all RPC and DOCUMENTbindings.

IN for non-holder parameters INOUT for

holder parameters.

header - FALSE

partName Used to specify the partName for the parameter

with RPCor DOCUMENT/BARE operations. @WebParam.name

Example 1:

@WebService(targetNamespace="http://duke.example.org", name="AddNumbers") public interface AddNumbersIF { @WebMethod(operationName="add", action="urn:addNumbers") @WebResult(name="return") public int addNumbers( @WebParam(name="num1")int number1, @WebParam(name="num2")int number2 ); }

Example 2:

@WebService(targetNamespace="http://duke.example.org", name="AddNumbers") public interface AddNumbersIF { @WebMethod(operationName="add", action="urn:addNumbers") @WebResult(name="return") public void addNumbers( @WebParam(name="num1")int number1, @WebParam(name="num2")int number2, @WebParam(name="result" mode=WebParam.Mode.OUT) Holder<Integer> result) throws AddNumbersException; }

• javax.jws.WebResult

This annotation is used to customize the mapping of the method return value to a WSDL part or XML element.

Table 4.4. javax.jws.WebResult

Property Description Default

Page 68: Chapter

Property Description Default

name

The name of the return value in the WSDL and on the

wire. For RPC bindings this is the part name of the

return value in the response message.

For DOCUMENT bindings this is the local name

of the XML element representing the return value.

"return" for RPC

and DOCUMENT/WRAPPED bindings.

Method name

+ "Response for DOCUMENT/BARE bindings.

targetNamespace - -

header - FALSE

partName Used to specify the partName for the result

with RPC orDOCUMENT/BARE operations. @WebResult.name

Example:

@WebService(targetNamespace="http://duke.example.org", name="AddNumbers") public interface AddNumbersIF { @WebMethod(operationName="add", action="urn:addNumbers") @WebResult(name="return") public int addNumbers( @WebParam(name="num1")int number1, @WebParam(name="num2")int number2 ); }

• javax.jws.HandlerChain

This annotation is used to specified an externally defined handler chain.

Table 4.5. javax.jws.HandlerChain

Property Description Default

file Location of the file containing the handler chain definition. The location can be relative or absolute with in a classpath system. If the location is relative, it is relative to the package of the web service. If it is absolute, it is absolute from some path on the classpath.

none

name DEPRECATED: The handler chain name from within the handler chain file. ""

Example:

@WebService @HandlerChain(file="handlers.xml") public class AddNumbersImpl { public int addNumbers(int number1, int number2) { return number1 + number2; } }

handlers.xml:

<jws:handler-config xmlns:jws="http://java.sun.com/xml/ns/javaee"> <jws:handler-chains> <jws:handler-chain> <jws:handler> <jws:handler-class>handler.common.LoggingHandler</jws:handler-class> </jws:handler> </jws:handler-chain>

Page 69: Chapter

</jws:handler-chains> </jws:handler-config>

You can only configure the server side handler by using the @HandlerChain annotation on the Service Endpoint Interface (SEI) or the server endpoint implementation class.

Use one of several ways to configure a client side handler. You can configure a client side handler by using

the @HandlerChain annotation on the generated service class or SEI. Additionally, you can programmatically register

your own implementation of the HandlerResolver interface on theService, or programmatically set the handler

chain on the Binding object.

• javax.jws.soap.SOAPBinding

JSR 181 also allows you to specify a SOAPBinding annotation on a endpoint implementation or service endpoint interface. This annotation lets the developer choose between document/literal wrapped, document/literal bare, rpc/literal and rpc/encoded endpoints with the default being document/literal wrapped. JAX-WS 2.1 does not support rpc/encoded.

The main difference between document/literal bare and document/literal wrapped is that methods on a document/literal wrapped endpoint can have multiple parameters bound to the body of a SOAP message, while a document/literal bare can only have one such parameter.

The main difference between document/literal wrapped and rpc/literal is that a document/literal invocation can be fully validated by a standard validating XML parser, while an rpc/literal invocation cannot because of the implied wrapper element around the invocation body.

Table 4.6. javax.jws.HandlerChain

Property Description Default

style Defines the style for messages used in a web service. The value can be

either DOCUMENT or RPC. DOCUMENT

use Defines the encoding used for messages used in web service. Can only

be LITERAL for JAX-WS 2.1 LITERAL

parameterStyle

Determines if the method's parameters represent the entire message body or whether the parameters are wrapped in a body element named after the operation.

Choice of WRAPPED or BARE. BARE can only be used

withDOCUMENT style bindings.

WRAPPED

Example:

@WebService(targetNamespace="http://duke.example.org", name="AddNumbers") @SOAPBinding(style=SOAPBinding.Style.RPC, use=SOAPBinding.Use.LITERAL) public interface AddNumbersIF { @WebMethod(operationName="add", action="urn:addNumbers") @WebResult(name="return") public int addNumbers( @WebParam(name="num1")int number1, @WebParam(name="num2")int number2 ); }

JSR 224 (JAX-WS) Annotations

• javax.xml.ws.BindingType

The BindingType annotation is used to specify the binding to use for a web service endpoint implementation class. As well as specify additional features that may be enabled.

This annotation may be overriden programmatically or via deployment descriptors, depending on the platform in use.

Page 70: Chapter

Example 1: Given the web service defined, the deployed endpoint would use the SOAP1.2 over HTTP binding:

@WebService @BindingType(value="http://www.w3.org/2003/05/soap/bindings/HTTP/") public class AddNumbersImpl { public int addNumbers(int number1, int number2) { return number1 + number2; } }

Example 2: Here is another sample use of the BindingType annotation that specifies use of the SOAP1.1/HTTP binding, it

enables both theAddressingFeature and the MTOMFeature and also sets the threshold feature parameter

on the MTOMFeature:

@WebService @BindingType(value=SOAPBinding.SOAP11HTTP_BINDING, features={ @Feature(AddressingFeature.ID), @Feature(value=MTOMFeature.ID, parameters={@FeatureParameter(name=MTOMFeature.THRESHOLD, value="1000")}) } ) public class MyWebService { ... }

NOTE: You can use the @BindingType annotation on the JavaBeans endpoint implementation class to enable MTOM by specifying

eitherjavax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING or javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_MTOM_BINDING as the value for the annotation.

• javax.xml.ws.RequestWrapper

This annotation annotates methods in the Service Endpoint Interface with the request wrapper bean to be used at runtime.

When starting from Java this annotation is used resolve overloading conflicts in document literal mode. Only

the className is required in this case.

Example:

public interface AddNumbersImpl { @WebMethod @WebResult(targetNamespace = "") @RequestWrapper(localName="addNumbers", targetNamespace="http://server.fromjava/", className="fromjava.client.AddNumbers") @ResponseWrapper(localName="addNumbersResponse", targetNamespace="http://server.fromjava/", className="fromjava.client.AddNumbersResponse") public int addNumbers( @WebParam(name = "arg0", targetNamespace = "") int arg0, @WebParam(name = "arg1", targetNamespace = "") int arg1); }

• javax.xml.ws.ResponseWrapper

This annotation annotates methods in the Service Endpoint Interface with the response wrapper bean to be used at runtime.

Page 71: Chapter

When starting from Java this annotation is used resolve overloading conflicts in document literal mode. Only

the className is required in this case.

Example:

public interface AddNumbersImpl { @WebMethod @WebResult(targetNamespace="") @RequestWrapper(localName="addNumbers", targetNamespace="http://server.fromjava/", className="fromjava.client.AddNumbers") @ResponseWrapper(localName="addNumbersResponse", targetNamespace="http://server.fromjava/", className="fromjava.client.AddNumbersResponse") public int addNumbers( @WebParam(name = "arg0", targetNamespace = "") int arg0, @WebParam(name = "arg1", targetNamespace = "") int arg1); }

• javax.xml.ws.ServiceMode

This annotation allows the Provider developer to indicate whether a Provider implementation wishes to work with entire protocol messages or just with protocol message payloads.

Example:

@WebServiceProvider(wsdlLocation="WEB-INF/wsdl/AddNumbers.wsdl") @ServiceMode(value=Service.Mode.PAYLOAD) public class AddNumbersImpl implements Provider<Source> { public Source invoke(Source source) throws RemoteException { try { DOMResult dom = new DOMResult(); Transformer trans = TransformerFactory.newInstance().newTransformer(); trans.transform(source, dom); Node node = dom.getNode(); Node root = node.getFirstChild(); Node first = root.getFirstChild(); int number1 = Integer.decode(first.getFirstChild().getNodeValue()); Node second = first.getNextSibling(); int number2 = Integer.decode(second.getFirstChild().getNodeValue()); return sendSource(number1, number2); } catch(Exception e) { e.printStackTrace(); throw new RemoteException("Error in provider endpoint"); } } private Source sendSource(int number1, int number2) { int sum = number1+number2; String body = "<ns:addNumbersResponse xmlns:ns=\"http://duke.example.org\"><return>" +sum +"</return></ns:addNumbersResponse>"; Source source = new StreamSource( new ByteArrayInputStream(body.getBytes())); return source; } }

NOTE: The @ServiceMode annotation is only supported on classes that are annotated with

the @WebServiceProvider annotation.

• javax.xml.ws.WebEndpoint

Page 72: Chapter

Used to annotate the get PortName() methods of a generated service interface.

The information specified in this annotation is sufficient to uniquely identify a wsdl:port element inside

a wsdl:service. The latter is determined based on the value of the @WebServiceClient annotation on the generated service interface itself.

Example:

@WebServiceClient(name="AddNumbersImplService", targetNamespace="http://server.fromjava/", wsdlLocation="http://localhost:8080/jaxws-fromjava/addnumbers?wsdl") public class AddNumbersImplService extends Service { private final static URL WSDL_LOCATION; private final static QName ADDNUMBERSIMPLSERVICE = new QName("http://server.fromjava/", "AddNumbersImplService"); private final static QName ADDNUMBERSIMPLPORT = new QName("http://server.fromjava/", "AddNumbersImplPort"); static { URL url = null; try { url = new URL("http://localhost:8080/jaxws-fromjava/addnumbers?wsdl"); } catch (MalformedURLException e) { e.printStackTrace(); } WSDL_LOCATION = url; } public AddNumbersImplService(URL wsdlLocation, QName serviceName) { super(wsdlLocation, serviceName); } public AddNumbersImplService() { super(WSDL_LOCATION, ADDNUMBERSIMPLSERVICE); } /** * * @return * returns AddNumbersImpl */ @WebEndpoint(name = "AddNumbersImplPort") public AddNumbersImpl getAddNumbersImplPort() { return (AddNumbersImpl)super.getPort(ADDNUMBERSIMPLPORT, AddNumbersImpl.class); } }

• javax.xml.ws.WebFault

This annotation is generated by the JAX-WS tools into service specific exception classes generated from a WSDL to customize to the local and namespace name of the fault element and the name of the fault bean and to mark the service specific exception as one generated from WSDL. Developers should not use this annotation themselves. The reason that the JAX-WS needs to know if a service specific exception is generated from a WSDL or not is because these exceptions will already have a fault bean generated for them. The name of this fault bean is not the same name as on generated from a Java service specific exception class. For more information on this topic, please refer to section 3.6 of the JAX-WS 2.0 specification.

Example:

@javax.xml.ws.WebFault(name="AddNumbersException", targetNamespace="http://server.fromjava/jaxws") public class AddNumbersException_Exception extends Exception { private fromjava.client.AddNumbersException faultInfo; public AddNumbersException_Exception(String message, AddNumbersException faultInfo) { super(message); this.faultInfo = faultInfo; } public AddNumbersException_Exception(String message, AddNumbersException faultInfo, Throwable cause) { super(message, cause); this.faultInfo = faultInfo;

Page 73: Chapter

} public fromjava.client.AddNumbersException getFaultInfo() { return faultInfo; } }

This annotation can only be applied to a fault implementation class on the client or server.

• javax.xml.ws.WebServiceClient

The information specified in this annotation is sufficient to uniquely identify a wsdl:service element inside a WSDL

document. This wsdl:serviceelement represents the Web service for which the generated service interface provides a client view.

Example:

@WebServiceClient(name="AddNumbersImplService", targetNamespace="http://server.fromjava/", wsdlLocation="http://localhost:8080/jaxws-fromjava/addnumbers?wsdl") public class AddNumbersImplService extends Service { private final static URL WSDL_LOCATION; private final static QName ADDNUMBERSIMPLSERVICE = new QName("http://server.fromjava/", "AddNumbersImplService"); private final static QName ADDNUMBERSIMPLPORT = new QName("http://server.fromjava/", "AddNumbersImplPort"); static { URL url = null; try { url = new URL("http://localhost:8080/jaxws-fromjava/addnumbers?wsdl"); } catch (MalformedURLException e) { e.printStackTrace(); } WSDL_LOCATION = url; } public AddNumbersImplService(URL wsdlLocation, QName serviceName) { super(wsdlLocation, serviceName); } public AddNumbersImplService() { super(WSDL_LOCATION, ADDNUMBERSIMPLSERVICE); } /** * * @return * returns AddNumbersImpl */ @WebEndpoint(name = "AddNumbersImplPort") public AddNumbersImpl getAddNumbersImplPort() { return (AddNumbersImpl)super.getPort(ADDNUMBERSIMPLPORT, AddNumbersImpl.class); } }

• javax.xml.ws.WebServiceProvider

Annotation used to annotate a Provider implementation class.

Example:

@ServiceMode(value=Service.Mode.PAYLOAD) @WebServiceProvider(wsdlLocation="WEB-INF/wsdl/AddNumbers.wsdl") public class AddNumbersImpl implements Provider { public Source invoke(Source source) {

Page 74: Chapter

try { DOMResult dom = new DOMResult(); Transformer trans = TransformerFactory.newInstance().newTransformer(); trans.transform(source, dom); Node node = dom.getNode(); Node root = node.getFirstChild(); Node first = root.getFirstChild(); int number1 = Integer.decode(first.getFirstChild().getNodeValue()); Node second = first.getNextSibling(); int number2 = Integer.decode(second.getFirstChild().getNodeValue()); return sendSource(number1, number2); } catch(Exception e) { e.printStackTrace(); throw new RuntimeException("Error in provider endpoint", e); } } private Source sendSource(int number1, int number2) { int sum = number1+number2; String body = "" + sum + ""; Source source = new StreamSource(new ByteArrayInputStream(body.getBytes())); return source; } }

NOTE:

o A Java class that implements a Web service must specify either

the @WebService or @WebServiceProvider annotation. Both annotations cannot be present.

o The @WebServiceProvider annotation is only supported on the service implementation class.

o Any class with the @WebServiceProvider annotation must implement

the javax.xml.ws.Provider interface.

• javax.xml.ws.WebServiceRef

The @WebServiceRef annotation is used to define a reference to a web service and (optionally) an injection target for it. Web service references are resources in the Java EE 5 sense.

Example:

import javax.xml.ws.WebServiceRef; import com.techtip.jaxws.sample.CalculatorService; import com.techtip.jaxws.sample.Calculator; public class JAXWSClient { @WebServiceRef(wsdlLocation="http://localhost:8080/CalculatorService?WSDL") static CalculatorService service; public void doTest() { try { Calculator port = service.getCalculatorPort(); int ret = port.add(2, 2); } catch(Exception e) { e.printStackTrace(); } } }

NOTE: The @WebServiceRef annotation can be used to inject instances of JAX-WS services and ports.

NOTE: The @WebServiceRef annotation is only supported in certain class types. Examples are JAX-WS endpoint implementation classes, JAX-WS handler classes, Enterprise JavaBeans classes, and servlet classes. This annotation is supported

in the same class types as the @Resourceannotation. See the Java Platform, Enterprise Edition (Java EE) 5 specification for a complete list of supported class types.

• javax.xml.ws.Feature

Page 75: Chapter

The @Feature annotation is used to enable/disable a feature to use for a web service endpoint implementation class. This

annotation is used with@BindingType annotation.

Here is a sample use of the @BindingType annotation that specifies use of the SOAP1.1/HTTP binding, it enables both

the AddressingFeature and theMTOMFeature and also sets the threshold feature parameter on

the MTOMFeature:

@BindingType( value=SOAPBinding.SOAP11HTTP_BINDING, features={ @Feature(AddressingFeature.ID), @Feature(value=MTOMFeature.ID, parameters={@FeatureParameter(name=MTOMFeature.THRESHOLD, value="1000")}) } ) public class MyWebService { ... }

• javax.xml.ws.FeatureParameter

The @FeatureParameter annotation is used to specify paramaters for a feature. This annotation is used

with @Feature.

• javax.xml.ws.Action

The @Action annotation allows explicit association of Action message addressing property with input, output, and fault messages of the mapped WSDL operation.

This annotation can be specified on each method of a service endpoint interface or implementation. For such a method, the

mapped operation in the generated WSDL contains explicit wsaw:Action attribute on the WSDL input, output and fault

messages of the WSDL operation based upon which attributes of the Action annotation have been specified.

Example: Specify explicit values for Action message addressing property for input and output messages:

@javax.jws.WebService public class AddNumbersImpl { @javax.xml.ws.Action( input="http://example.com/inputAction", output="http://example.com/outputAction") public int addNumbers(int number1, int number2) { return number1 + number2; } }

The generated WSDL looks like:

<definitions targetNamespace="http://example.com/numbers" ...> ... <portType name="AddNumbersPortType"> <operation name="AddNumbers"> <input message="tns:AddNumbersInput" name="Parameters" wsaw:Action="http://example.com/inputAction"/> <output message="tns:AddNumbersOutput" name="Result" wsaw:Action="http://example.com/outputAction"/> </operation> <portType> ... <definitions>

Page 76: Chapter

• javax.xml.ws.FaultAction

The @FaultAction annotation is used inside an @Action annotation to allow an explicit association

of Action message addressing property with the fault messages of the WSDL operation mapped from the exception class.

The fault message in the generated WSDL operation mapped for className class contains

explicit wsaw:Action attribute.

Example: Specify explicit values for Action message addressing property for the input, output and fault message if the Java method throws only one service specific exception:

@javax.jws.WebService public class AddNumbersImpl { @javax.xml.ws.Action( input="http://example.com/inputAction", output="http://example.com/outputAction", fault = {@javax.xml.ws.FaultAction(className=AddNumbersException.class, value="http://example.com/faultAction")} ) public int addNumbers(int number1, int number2) throws AddNumbersException { return number1 + number2; } }

The generated WSDL looks like:

<definitions targetNamespace="http://example.com/numbers" ...> ... <portType name="AddNumbersPortType"> <operation name="AddNumbers"> <input message="tns:AddNumbersInput" name="Parameters" wsaw:Action="http://example.com/inputAction"/> <output message="tns:AddNumbersOutput" name="Result" wsaw:Action="http://example.com/outputAction"/> <fault message="tns:AddNumbersException" name="AddNumbersException" wsaw:Action="http://example.com/faultAction"/> </operation> <portType> ... <definitions>

Describe the architecture of JAX-WS including the Tools SPI that define the contract between JAX-WS tools and Java EE.

• [NONE] blah

Page 77: Chapter

The JAX-WS RI consists of the following major modules:

• Runtime

Runtime module is available at application runtime and provide the actual core Web Services framework.

JAX-WS is the aggregating component of what is called the integrated Stack (I-Stack). The I-Stack consists of JAX-WS, JAXB, StAX, SAAJ and Fast Infoset. JAXB is the databinding component of the stack. StAX is the Streaming XML parser used by the stack. SAAJ is used for its attachment support with SOAP messages and to allow handler developers to gain access to the SOAP message via a standard interface. Fast Infoset is a binary encoding of XML that can improve performance.

• Tools

Tools for converting WSDLs and Java source/class files to Web Services.

o APT

A Java SE tool and framework for processing annotations. APT will invoke a JAX-

WS AnnotationProcossor for processing Java source files withjavax.jws.* annotations and making them web services. APT will compile the Java source files and generate any additional classes needed to make

an javax.jws.WebService annotated class a Web service.

o WsGen

Tool to process a compiled javax.jws.WebService annotated class and to generate the necessary classes to make it a Web service.

o WsImport

Tool to import a WSDL and to generate an SEI (a javax.jws.WebService) interface that can be either implemented on the server to build a web service, or can be used on the client to invoke the web service.

• APT

Page 78: Chapter

A Java SE tool and framework for processing annotations.

apt [-classpath classpath] [-sourcepath sourcepath] [-d directory] [-s directory] [-factorypath path] [-factory class] [-print] [-nocompile] [-Akey[=val] ...] [javac option] sourcefiles [@files] -s dir Specify the directory root under which processor-generated source files will be placed; files are placed in subdirectories based on package namespace. -nocompile Do not compile source files to class files. -print Print out textual representation of specified types; perform no annotation processing or compilation. -A[key[=val]] Options to pass to annotation processors -- these are not interpreted by apt directly, but are made available for use by individual processors -factorypath path Specify where to find annotation processor factories; if this option is used, the classpath is not searched for factories. -factory classname Name of annotation processor factory to use; bypasses default discovery process -d dir Specify where to place processor and javac generated class files -cp path or -classpath path Specify where to find user class files and annotation processor factories. If -factorypath is given, the classpath is not searched for factories.

The tool apt, annotation processing tool, includes a set of new reflective APIs and supporting infrastructure to process program

annotations. The aptreflective APIs provide a build-time, source-based, read-only view of program structure. These reflective

APIs are designed to cleanly model the Java programming language's type system after the addition of generics. First, apt runs

annotation processors that can produce new source code and other files. Next, apt can cause compilation of both original and generated source files, easing development. The reflective APIs and other APIs used to interact with the tool are subpackages

of com.sun.mirror.

• Annotation Processor

An APT AnnotationProcessor for processing Java source files with javax.jws.* annotations and making them web services.

• Runtime SPI

A part of JAX-WS that defines the contract between the JAX-WS RI runtime and Java EE.

• Tools SPI

A part of JAX-WS that defines the contract between the JAX-WS RI tools and Java EE.

• JAXB XJC-API

The schema compiler.

• JAXB runtime-API

A part of the JAXB runtime that defines the contract between the JAXB RI and the JAX-WS RI.

Describe creating a Web Service using JAX-WS.

Page 79: Chapter

• [JAVA_EE_5_TUTORIAL] The Java EE 5 Tutorial

The starting point for developing a JAX-WS web service is a Java class annotated with the javax.jws.WebService annotation.

The @WebService annotation defines the class as a web service endpoint.

A service endpoint interface or service endpoint implementation (SEI) is a Java interface or class, respectively, that declares the methods that a client can invoke on the service. An interface is not required when building a JAX-WS endpoint. The web service implementation class implicitly defines an SEI.

You may specify an explicit interface by adding the endpointInterface element to the @WebService annotation in the implementation class. You must then provide an interface that defines the public methods made available in the endpoint implementation class.

You use the endpoint implementation class and the wsgen tool to generate the web service artifacts that connect a web service client to the JAX-WS runtime.

Together, the wsgen tool and the Application Server provide the Application Server's implementation of JAX-WS.

These are the basic steps for creating the web service and client:

1. Code the implementation class. 2. Compile the implementation class.

3. Use wsgen to generate the artifacts required to deploy the service. 4. Package the files into a WAR file. 5. Deploy the WAR file. The web service artifacts (which are used to communicate with clients) are generated by the Application

Server during deployment. 6. Code the client class.

7. Use wsimport to generate and compile the web service artifacts needed to connect to the service. 8. Compile the client class. 9. Run the client.

Requirements of a JAX-WS Endpoint

JAX-WS endpoints must follow these requirements:

• The implementing class must be annotated with either

the javax.jws.WebService or javax.jws.WebServiceProvider annotation.

• The implementing class may explicitly reference an SEI through the endpointInterface element of

the @WebService annotation, but is not required to do so. If no endpointInterface is specified

in @WebService, an SEI is implicitly defined for the implementing class.

• The business methods of the implementing class must be public, and must NOT be declared static or final.

• Business methods that are exposed to web service clients must be annotated with javax.jws.WebMethod.

• Business methods that are exposed to web service clients must have JAXB-compatible parameters and return types.

• The implementing class must NOT be declared final and must NOT be abstract.

• The implementing class must have a default public constructor.

• The implementing class must NOT define the finalize() method.

• The implementing class may use

the javax.annotation.PostConstruct or javax.annotation.PreDestroy annotations on its methods for life cycle event callbacks.

The @PostConstruct method is called by the container before the implementing class begins responding to web service clients.

The @PreDestroy method is called by the container before the endpoint is removed from operation.

Coding the Service Endpoint Implementation Class

Page 80: Chapter

In this example, the implementation class, Hello, is annotated as a web service endpoint using

the @WebService annotation. Hello declares a single method named sayHello, annotated with

the @WebMethod annotation. @WebMethod exposes the annotated method to web service clients. sayHello returns a

greeting to the client, using the name passed to sayHello to compose the greeting. The implementation class also must define a default, public, no-argument constructor.

package helloservice.endpoint; import javax.jws.WebService; @WebService public class Hello { private String message = new String("Hello, "); public void Hello() {} @WebMethod public String sayHello(String name) { return message + name + "."; } }

A Simple JAX-WS Client

HelloClient is a stand-alone Java program that accesses the sayHello method of HelloService. It makes this call through a port, a local object that acts as a proxy for the remote service. The port is created at development time by

the wsimport tool, which generates JAX-WS portable artifacts based on a WSDL file.

When invoking the remote methods on the port, the client performs these steps:

1. Uses the javax.xml.ws.WebServiceRef annotation to declare a reference to a web

service. @WebServiceRef uses the wsdlLocation element to specify the URI of the deployed service's WSDL file:

2. @WebServiceRef(wsdlLocation="http://localhost:8080/helloservice/hello?wsdl") 3. static HelloService service;

4. Retrieves a proxy to the service, also known as a port, by invoking getHelloPort on the service.

5. Hello port = service.getHelloPort();

The port implements the SEI defined by the service.

6. Invokes the port's sayHello method, passing to the service a name.

7. String response = port.sayHello(name);

Here is the full source of HelloClient:

package simpleclient; import javax.xml.ws.WebServiceRef; import helloservice.endpoint.HelloService; import helloservice.endpoint.Hello; public class HelloClient { @WebServiceRef(wsdlLocation="http://localhost:8080/helloservice/hello?wsdl") static HelloService service; public static void main(String[] args) { try { HelloClient client = new HelloClient();

Page 81: Chapter

client.doTest(args); } catch(Exception e) { e.printStackTrace(); } } public void doTest(String[] args) { try { System.out.println("Retrieving the port from the following service: " + service); Hello port = service.getHelloPort(); System.out.println("Invoking the sayHello operation on the port."); String name; if (args.length > 0) { name = args[0]; } else { name = "No Name"; } String response = port.sayHello(name); System.out.println(response); } catch(Exception e) { e.printStackTrace(); } } }

Describe JAX-WS Client Communications Models.

• [NONE] blah

The Java API for XML-Based Web Services (JAX-WS) Web service client programming model supports both the Dispatch client API and the Dynamic Proxy client API. The Dispatch client API is a dynamic client programming model, whereas the static client programming model for JAX-WS is the Dynamic Proxy client. The Dispatch and Dynamic Proxy clients enable both synchronous and asynchronous invocation of JAX-WS Web services.

• Dispatch client: Use this client when you want to work at the XML message level or when you want to work without any generated artifacts at the JAX-WS level.

• Dynamic Proxy client: Use this client when you want to invoke a Web service based on a service endpoint interface.

Dispatch client

XML-based Web services use XML messages for communications between Web services and Web services clients. The JAX-WS APIs provide high-level methods to simplify and hide the details of converting between Java method invocations and their associated XML messages. However, in some cases, you might desire to work at the XML message level. Support for invoking services at the XML message level is provided by the Dispatch client API.

The Dispatch client API, javax.xml.ws.Dispatch, is a dynamic JAX-WS client programming interface. To write a Dispatch client, you must have expertise with the Dispatch client APIs, the supported object types, and knowledge of the message representations for the associated Web Services Description Language (WSDL) file. The Dispatch client can send data in

either MESSAGE or PAYLOAD mode.

When using the javax.xml.ws.Service.Mode.MESSAGE mode, the Dispatch client is responsible for providing the

entire SOAP envelope including thesoap:Envelope, soap:Header, and soap:Body elements.

When using the javax.xml.ws.Service.Mode.PAYLOAD mode, the Dispatch client is only responsible for providing

the contents of the soap:Body and JAX-WS includes the payload in a soap:Envelope element.

The Dispatch client API requires application clients to construct messages or payloads as XML which requires a detailed knowledge of the message or message payload. The Dispatch client supports the following types of objects:

Page 82: Chapter

• javax.xml.transform.Source: Use Source objects to enable clients to use XML APIs directly. You can use Source objects with SOAP or HTTP bindings.

• JAXB objects: Use JAXB objects so that clients can use JAXB objects that are generated from an XML schema to create and manipulate XML with JAX-WS applications. JAXB objects can only be used with SOAP or HTTP bindings.

• javax.xml.soap.SOAPMessage: Use SOAPMessage objects so that clients can work with SOAP

messages. You can only use SOAPMessage objects with SOAP bindings.

• javax.activation.DataSource: Use DataSource objects so that clients can work with Multipurpose

Internet Mail Extension (MIME) messages. UseDataSource only with HTTP bindings.

For example, if the input parameter type is javax.xml.transform.Source, the call to the Dispatch client API is similar to the following code example:

Dispatch<Source> dispatch = ... ; //create a Dispatch<Source> Source request = ... ; //create a Source object Source response = dispatch.invoke(request);

The Dispatch parameter value determines the return type of the invoke() method.

The Dispatch client is invoked in one of three ways:

• Synchronous invocation for requests and responses using the invoke method

• Asynchronous invocation for requests and responses using the invokeAsync method with a callback or polling object

• One-way invocation using the invokeOneWay methods

The following examples demonstrate use of Dispatch methods in the synchronous, asynchronous polling, and asynchronous callback modes.

• Synchronous, Payload-Oriented

• Source reqMsg = ...;

• Service service = ...;

• Dispatch<Source> disp = service.createDispatch(portName, Source.class, PAYLOAD);

• Source resMsg = disp.invoke(reqMsg);

• Synchronous, Message-Oriented

• SOAPMessage soapReqMsg = ...;

• Service service = ...;

• Dispatch<SOAPMessage> disp = service.createDispatch(portName, SOAPMessage.class, MESSAGE);

• SOAPMessage soapResMsg = disp.invoke(soapReqMsg);

• Synchronous, Payload-Oriented With JAXB Objects

• JAXBContext jc = JAXBContext.newInstance("primer.po");

• Unmarshaller u = jc.createUnmarshaller();

• PurchaseOrder po = (PurchaseOrder)u.unmarshal(new FileInputStream("po.xml"));

• Service service = ...;

Page 83: Chapter

• Dispatch<Object> disp = service.createDispatch(portName, jc, PAYLOAD);

• OrderConfirmation conf = (OrderConfirmation)disp.invoke(po);

• Asynchronous, Polling, Message-Oriented

• SOAPMessage soapReqMsg = ...;

• Service service = ...;

• Dispatch<SOAPMessage> disp = service.createDispatch(portName, SOAPMessage.class, MESSAGE);

• Response<SOAPMessage> res = disp.invokeAsync(soapReqMsg);

• while (!res.isDone()) {

• // do something while we wait

• }

• SOAPMessage soapResMsg = res.get();

• Asynchronous, Callback, Payload-Oriented

• class MyHandler implements AsyncHandler<Source> {

• ...

• public void handleResponse(Response<Source> res) {

• Source resMsg = res.get();

• // do something with the results

• }

• }

• Source reqMsg = ...;

• Service service = ...;

• Dispatch<Source> disp = service.createDispatch(portName, Source.class, PAYLOAD);

• MyHandler handler = new MyHandler();

• disp.invokeAsync(reqMsg, handler);

Dynamic Proxy client

The static client programming model for JAX-WS is the called the Dynamic Proxy client. The Dynamic Proxy client invokes a Web service based on a Service Endpoint Interface (SEI) which must be provided. The Dynamic Proxy client is similar to the stub client in the Java API for XML-based RPC (JAX-RPC) programming model. Although the JAX-WS Dynamic Proxy client and the JAX-RPC stub client are both based on the Service Endpoint Interface (SEI) that is generated from a WSDL file , there is a major difference. The Dynamic Proxy client is dynamically generated at run time using the Java 5 Dynamic Proxy functionality, while the JAX-RPC-based stub client is a non-portable Java file that is generated by tooling. Unlike the JAX-RPC stub clients, the Dynamic Proxy client does not require you to regenerate a stub prior to running the client on an application server for a different vendor because the generated interface does not require the specific vendor information.

The Dynamic Proxy instances extend the java.lang.reflect.Proxy class and leverage the Dynamic Proxy function in the base Java Runtime Environment Version 5. The client application can then provide an interface that is used to create the proxy instance while the runtime is responsible for dynamically creating a Java object that represents the SEI.

The following example shows the use of a proxy to invoke a method (getLastTradePrice) on a service endpoint interface

(com.example.StockQuoteProvider). Note that no statically generated stub class is involved.

Page 84: Chapter

javax.xml.ws.Service service = ... ; com.example.StockQuoteProvider proxy = service.getPort(portName, com.example.StockQuoteProvider.class); javax.xml.ws.BindingProvider bp = (javax.xml.ws.BindingProvider)proxy; Map<String,Object> context = bp.getRequestContext(); context.setProperty("javax.xml.ws.session.maintain", Boolean.TRUE); proxy.getLastTradePrice("ACME");

Given a set of requirements, create and configure a Web service client that accesses a stateful Web service.

• [NONE] blah

Traditionally JAX-WS has never taken advantage of object state, just like servlet. That is, the container creates only one instance of your service class, and then have it serve all the requests concurrently. This makes it impossible to set values to instance fields, as you will experience concurrency problem as soon as multiple threads hit your service.

On HTTP, session is often used to store state. This technique is still useful for web services over HTTP. JAX-WS lets you do this today:

@WebService public class Hello { @Resource private WebServiceContext wsContext; public int getCounter() { MessageContext msgContext = wsContext.getMessageContext(); HttpServletRequest request = (HttpServletRequest) msgContext.get(MessageContext.SERVLET_REQUEST); HttpSession session = request.getSession(); // Get a session property "counter" from context if (session == null) { throw new WebServiceException("No session in WebServiceContext"); } Integer counter = (Integer)session.getAttribute("counter"); if (counter == null) { counter = new Integer(0); System.out.println("Starting the Session"); } counter = new Integer(counter.intValue() + 1); session.setAttribute("counter", counter); return counter; } }

When the JAX-WS stack implementation you are running your web services on is deploying your web service endpoint, it will inject an

instance ofWebServiceContext into the implementation instance. You can then ask it for a MessageContext, and from this get the request, session, response etc.

NOTE: By doing this, you are binding your implementation to knowledge about which transport mechanism, it is deployed on and accessed through. It could be something else than HTTP.

Using @HttpSessionScope

One way to bring state to Web Services is to use HttpSession cookies. Storing the state and accessing it from

the HttpSession (from WebServiceContext) for each request takes multiple steps and does not fit well with the OO way of accessing/storing it with instance fields. One can

[email protected] annotation tells the JAX-WS RI to

create one instance of Hello per each HTTP session. As you see this approach still relies on Http cookies but makes it easier to access state from the context just like normal instance variables:

Page 85: Chapter

@HttpSessionScope @WebService public class Hello { int counter = 0; public int getCounter() { return counter++; } }

Using @Stateful

JAX-WS also provides a transport neutral mechanism to do this. It

introduces @com.sun.xml.ws.developer.Stateful to take care of maintaining all the state and the user can

access it using instance variables. All the user needs to do is to add @Stateful to Web Service implementation.

The JAX-WS RI has a vendor extension that allows developers to bring back object state to the web service world. Normally, the JAX-WS RI only creates one instance of a service class, and have it serve all incoming requests concurrently. This makes it essentially impossible to use instance fields of the service class for any meaningful purpose.

The stateful web service support in the JAX-WS RI resolves this problem by having the JAX-WS RI maintain multiple instances of a service. By using WS-Addressing behind the scene, it provides a standard-based on-the-wire protocol and easy-to-use programming model.

Application service implementation classes (or providers) who'd like to use the stateful web service support must

declare @Stateful annotation on a class. It should also have a public static method/field that

takes StatefulWebServiceManager:

@Stateful @WebService @Addressing class BankAccount { protected final int id; private int balance; Account(int id) { this.id = id; } @WebMethod public synchronized void deposit(int amount) { balance+=amount; } // either via a public static field public static StatefulWebServiceManager<BankAccount> manager; // or via a public static method (the method name could be anything) public static void setManager(StatefulWebServiceManager<BankAccount> manager) { ... } }

After your service is deployed but before you receive a first request, the resource injection occurs on the field or the method.

A stateful web service class does not need to have a default constructor. In fact, most of the time you want to define a constructor that takes some arguments, so that each instance carries certain state (as illustrated in the above example).

Each instance of a stateful web service class is identified by an unique EndpointReference. Your application creates an instance of a class, then you'll have the JAX-WS RI assign this unique EPR for the instance as follows:

@WebService class Bank { // this is ordinary stateless service @WebMethod public synchronized W3CEndpointReference login(int accountId, int pin) { if(!checkPin(pin)) { throw new AuthenticationFailedException("invalid pin"); } BankAccount acc = new BankAccount(accountId); return BankAccount.manager.export(acc); } }

Page 86: Chapter

Typically you then pass this EPR to remote systems. When they send messages to this EPR, the JAX-WS RI makes sure that the particular exported instance associated with that EPR will receive a service invocation.

Chapter 5. REST, JSON, SOAP and XML Processing APIs (JAXP, JAXB and SAAJ)

Describe the characteristics of REST Web Services.

• [NONE] blah

REST defines a set of architectural principles by which you can design Web services that focus on a system's resources, including how resource states are addressed and transferred over HTTP by a wide range of clients written in different languages. REST has a large impact on the Web that it has mostly displaced SOAP- and WSDL-based interface design because it's a considerably simpler style to use.

A concrete implementation of a REST Web service follows four basic design principles:

• Use HTTP methods explicitly

One of the key characteristics of a RESTful Web service is the explicit use of HTTP methods in a way that follows the protocol as defined by RFC 2616. HTTP GET, for instance, is defined as a data-producing method that's intended to be used by a client application to retrieve a resource, to fetch data from a Web server, or to execute a query with the expectation that the Web server will look for and respond with a set of matching resources.

REST asks developers to use HTTP methods explicitly and in a way that's consistent with the protocol definition. This basic REST design principle establishes a one-to-one mapping between create, read, update, and delete (CRUD) operations and HTTP methods. According to this mapping:

o To create a resource on the server, use POST.

o To retrieve a resource, use GET.

o To change the state of a resource or to update it, use PUT.

o To remove or delete a resource, use DELETE.

An unfortunate design flaw inherent in many Web APIs is in the use of HTTP methods for unintended purposes. The request URI in an HTTP GET request, for example, usually identifies one specific resource. Or the query string in a request URI includes a set of parameters that defines the search criteria used by the server to find a set of matching resources. At least this is how the HTTP/1.1 RFC describes GET. But there are many cases of unattractive Web APIs that use HTTP GET to trigger something transactional on the server—for instance, to add records to a database. In these cases the GET request URI is not used properly or at least not used RESTfully. If the Web API uses GET to invoke remote procedures, it looks like this:

GET /adduser?name=Mikalai HTTP/1.1

It's not a very attractive design because the Web method above supports a state-changing operation over HTTP GET. Put another way, the HTTP GET request above has side effects. If successfully processed, the result of the request is to add a new user—in this example, Robert—to the underlying data store. The problem here is mainly semantic. Web servers are designed to respond to HTTP GET requests by retrieving resources that match the path (or the query criteria) in the request URI and return these or a representation in a response, not to add a record to a database. From the standpoint of the intended use of the protocol method then, and from the standpoint of HTTP/1.1-compliant Web servers, using GET in this way is inconsistent.

Beyond the semantics, the other problem with GET is that to trigger the deletion, modification, or addition of a record in a database, or to change server-side state in some way, it invites Web caching tools (crawlers) and search engines to make server-side changes unintentionally simply by crawling a link. A simple way to overcome this common problem is to move the parameter names and values on the request URI into XML tags. The resulting tags, an XML representation of the entity to create, may be sent in the body of an HTTP POST whose request URI is the intended parent of the entity:

POST /users HTTP/1.1 Host: myserver Content-Type: application/xml <?xml version="1.0"?> <user> <name>Mikalai</name> </user>

Page 87: Chapter

The method above is exemplary of a RESTful request: proper use of HTTP POST and inclusion of the payload in the body of the request. On the receiving end, the request may be processed by adding the resource contained in the body as a subordinate of

the resource identified in the request URI; in this case the new resource should be added as a child of /users. This containment relationship between the new entity and its parent, as specified in the POST request, is analogous to the way a file is subordinate to its parent directory. The client sets up the relationship between the entity and its parent and defines the new entity's URI in the POST request.

A client application may then get a representation of the resource using the new URI, noting that at least logically the resource is

located under/users, as shown below:

GET /users/Mikalai HTTP/1.1 Host: myserver Accept: application/xml

Using GET in this way is explicit because GET is for data retrieval only. GET is an operation that should be free of side effects, a property also known as idempotence.

A similar refactoring of a Web method also needs to be applied in cases where an update operation is supported over HTTP GET, as shown in listing below:

GET /updateuser?name=Mikalai&newname=Mikola HTTP/1.1

This changes the name attribute (or property) of the resource. While the query string can be used for such an operation, this query-string-as-method-signature pattern tends to break down when used for more complex operations. Because your goal is to make explicit use of HTTP methods, a more RESTful approach is to send an HTTP PUT request to update the resource, instead of HTTP GET, for the same reasons stated above:

PUT /users/Mikalai HTTP/1.1 Host: myserver Content-Type: application/xml <?xml version="1.0"?> <user> <name>Mikola</name> </user>

Using PUT to replace the original resource provides a much cleaner interface that's consistent with REST's principles and with the definition of HTTP methods. The PUT request in the listing above is explicit in the sense that it points at the resource to be updated by identifying it in the request URI and in the sense that it transfers a new representation of the resource from client to server in the body of a PUT request instead of transferring the resource attributes as a loose set of parameter names and values

on the request URI. Listing above also has the effect of renaming the resource from Mikalai to Mikola, and in doing so

changes its URI to /users/Mikola. In a REST Web service, subsequent requests for the resource using the old URI would generate a standard 404 Not Found error.

As a general design principle, it helps to follow REST guidelines for using HTTP methods explicitly by using nouns in URIs instead of verbs. In a RESTful Web service, the verbs - POST, GET, PUT, and DELETE - are already defined by the protocol. And ideally, to keep the interface generalized and to allow clients to be explicit about the operations they invoke, the Web service should not

define more verbs or remote procedures, such as /adduseror /updateuser. This general design principle also applies to the body of an HTTP request, which is intended to be used to transfer resource state, not to carry the name of a remote method or remote procedure to be invoked.

• Be stateless

REST Web services need to scale to meet increasingly high performance demands. Clusters of servers with load-balancing and failover capabilities, proxies, and gateways are typically arranged in a way that forms a service topology, which allows requests to be forwarded from one server to the other as needed to decrease the overall response time of a Web service call. Using intermediary servers to improve scale requires REST Web service clients to send complete, independent requests; that is, to send requests that include all data needed to be fulfilled so that the components in the intermediary servers may forward, route, and load-balance without any state being held locally in between requests.

A complete, independent request doesn't require the server, while processing the request, to retrieve any kind of application context or state. A REST Web service application (or client) includes within the HTTP headers and body of a request all of the parameters, context, and data needed by the server-side component to generate a response. Statelessness in this sense improves

Page 88: Chapter

Web service performance and simplifies the design and implementation of server-side components because the absence of state on the server removes the need to synchronize session data with an external application.

Figure below illustrates a stateful service from which an application may request the next page in a multipage result set, assuming that the service keeps track of where the application leaves off while navigating the set. In this stateful design, the

service increments and stores a previousPagevariable somewhere to be able to respond to requests for next.

Stateful services like this get complicated. In a Java Platform, Enterprise Edition (Java EE) environment stateful services require a lot of up-front consideration to efficiently store and enable the synchronization of session data across a cluster of Java EE containers. In this type of environment, there's a problem familiar to Servlet/JavaServer Pages (JSP) and Enterprise JavaBeans (EJB) developers who often struggle to find the root causes

ofjava.io.NotSerializableException during session replication. Whether it's thrown by the servlet

container during HttpSession replication or thrown by the EJB container during stateful EJB replication, it's a problem

that can cost developers days in trying to pinpoint the one object that doesn't implement Serializable in a sometimes complex graph of objects that constitute the server's state. In addition, session synchronization adds overhead, which impacts server performance.

Stateless server-side components, on the other hand, are less complicated to design, write, and distribute across load-balanced servers. A stateless service not only performs better, it shifts most of the responsibility of maintaining state to the client application. In a RESTful Web service, the server is responsible for generating responses and for providing an interface that enables the client to maintain application state on its own. For example, in the request for a multipage result set, the client should include the actual page number to retrieve instead of simply asking for next:

A stateless Web service generates a response that links to the next page number in the set and lets the client do what it needs to in order to keep this value around. This aspect of RESTful Web service design can be broken down into two sets of responsibilities as a high-level separation that clarifies just how a stateless service can be maintained:

o Server

Generates responses that include links to other resources to allow applications to navigate between related resources. This type of response embeds links. Similarly, if the request is for a parent or container resource, then a typical RESTful response might also include links to the parent's children or subordinate resources so that these remain connected.

Generates responses that indicate whether they are cacheable or not to improve performance by reducing the number of requests for duplicate resources and by eliminating some requests entirely. The server does this by including

a Cache-Control and Last-Modified (a date value) HTTP response header.

o Client application

Page 89: Chapter

Uses the Cache-Control response header to determine whether to cache the resource (make a local copy

of it) or not. The client also reads theLast-Modified response header and sends back the date value in

an If-Modified-Since header to ask the server if the resource has changed. This is called Conditional GET, and the two headers go hand in hand in that the server's response is a standard 304 code (Not Modified) and omits the actual resource requested if it has not changed since that time. A 304 HTTP response code means the client can safely use a cached, local copy of the resource representation as the most up-to-date, in effect bypassing subsequent GET requests until the resource changes.

Sends complete requests that can be serviced independently of other requests. This requires the client to make full use of HTTP headers as specified by the Web service interface and to send complete representations of resources in the request body. The client sends requests that make very few assumptions about prior requests, the existence of a session on the server, the server's ability to add context to a request, or about application state that is kept in between requests.

This collaboration between client application and service is essential to being stateless in a RESTful Web service. It improves performance by saving bandwidth and minimizing server-side application state.

• Expose directory structure-like URIs

From the standpoint of client applications addressing resources, the URIs determine how intuitive the REST Web service is going to be and whether the service is going to be used in ways that the designers can anticipate.

REST Web service URIs should be intuitive to the point where they are easy to guess. Think of a URI as a kind of self-documenting interface that requires little, if any, explanation or reference for a developer to understand what it points to and to derive related resources. To this end, the structure of a URI should be straightforward, predictable, and easily understood.

One way to achieve this level of usability is to define directory structure-like URIs. This type of URI is hierarchical, rooted at a single path, and branching from it are subpaths that expose the service's main areas. According to this definition, a URI is not merely a slash-delimited string, but rather a tree with subordinate and superordinate branches connected at nodes. For example, in a discussion threading service that gathers topics ranging from Java to paper, you might define a structured set of URIs like this:

http://www.myservice.org/discussion/topics/{topic}

The root, /discussion, has a /topics node beneath it. Underneath that there are a series of topic names, such as gossip, technology, and so on, each of which points to a discussion thread. Within this structure, it's easy to pull up discussion

threads just by typing something after /topics/.

In some cases, the path to a resource lends itself especially well to a directory-like structure. Take resources organized by date, for instance, which are a very good match for using a hierarchical syntax.

This example is intuitive because it is based on rules:

http://www.myservice.org/discussion/2008/12/10/{topic}

The first path fragment is a four-digit year, the second path fragment is a two-digit day, and the third fragment is a two-digit month. It may seem a little silly to explain it that way, but this is the level of simplicity we're after. Humans and machines can easily generate structured URIs like this because they are based on rules. Filling in the path parts in the slots of a syntax makes them good because there is a definite pattern from which to compose them:

http://www.myservice.org/discussion/{year}/{day}/{month}/{topic}

Some additional guidelines to make note of while thinking about URI structure for a RESTful Web service are:

o Hide the server-side scripting technology file extensions (.jsp, .php, .asp), if any, so you can port to something else without changing the URIs.

o Keep everything lowercase.

o Substitute spaces with hyphens or underscores (one or the other).

o Avoid query strings as much as you can.

o Instead of using the 404 Not Found code if the request URI is for a partial path, always provide a default page or resource as a response.

Page 90: Chapter

URIs should also be static so that when the resource changes or the implementation of the service changes, the link stays the same. This allows bookmarking. It's also important that the relationship between resources that's encoded in the URIs remains independent of the way the relationships are represented where they are stored.

• Transfer XML, JSON, or both

A resource representation typically reflects the current state of a resource, and its attributes, at the time a client application requests it. Resource representations in this sense are mere snapshots in time. This could be a thing as simple as a representation of a record in a database that consists of a mapping between column names and XML tags, where the element values in the XML contain the row values. Or, if the system has a data model, then according to this definition a resource representation is a snapshot of the attributes of one of the things in your system's data model. These are the things you want your REST Web service to serve up.

The last set of constraints that goes into a RESTful Web service design has to do with the format of the data that the application and service exchange in the request/response payload or in the HTTP body. This is where it really pays to keep things simple, human-readable, and connected.

The objects in your data model are usually related in some way, and the relationships between data model objects (resources) should be reflected in the way they are represented for transfer to a client application. In the discussion threading service, an example of connected resource representations might include a root discussion topic and its attributes, and embed links to the responses given to that topic:

<?xml version="1.0"?> <discussion date="{date}" topic="{topic}"> <comment>{comment}</comment> <replies> <reply from="[email protected]" href="/discussion/topics/{topic}/joe"/> <reply from="[email protected]" href="/discussion/topics/{topic}/rob"/> </replies> </discussion>

To give client applications the ability to request a specific content type that's best suited for them, construct your service so that it

makes use of the built-in HTTP Accept header, where the value of the header is a MIME type. Some common MIME types used by RESTful services are shown in table:

Table 5.1. Common MIME types used by RESTful services

MIME-Type Content-Type

JSON application/json

XML application/xml

XHTML application/xhtml+xml

Describe the characteristics of JSON Web Services.

• [NONE] blah

JAX-WS supports a "pluggable encoding" - meaning it can use formats other than textual XML. This extension takes advantage of this and allows JAX-WS services to be exposed via JSON.

JSON support is implemented as a custom binding. So just like there are SOAP/HTTP binding or Plain Old XML binding, you can specify JSON binding to expose a service as JSON service. The following code shows one way of exposing a service over JSON:

@BindingType(JSONBindingID.JSON_BINDING) public class MyService { public Book get(@WebParam(name="id") int id) {

Page 91: Chapter

Book b = new Book(); b.id = id; return b; } public static final class Book { public int id = 1; public String title = "Java"; } }

You just need jaxws-json.jar in your WEB-INF/lib for this to work.

Client-side Programming

Once the server exposes a JSON service, you'll write client-side JavaScript to access this service. First, you'll include the proxy script.

<script src="path/to/endpoint?js"></script>

This creates a variable 'myService' with which you can make service invocations. All the parameters are passed as a single JavaScript object, where the property name is the parameter name. The call happens asynchronously, and when it's done your callback will be invoked with the return value as a parameter:

myService.get( {id:5}, function(r) { alert("ID="+r.id); alert("title="+r.title); } );

If you'd like to use a different variable name, specify that as the var query parameter, as shown below:

<script src="path/to/endpoint?js&var=svc"></script>

For client-side development, JSON endpoints serve HTML documentations on the fly, including all the available operations and "type descriptions" for all parameters and return values.

Compare SOAP web services to REST Web Services.

• [NONE] blah

In software engineering, the term software architectural style generally refers to "a set of design rules that identify the kinds of components and connectors that may be used to compose a system or subsystem."

Some common examples of architectural styles include the Pipe and Filter, Layered, Push Based, and so on. In the web services world, REpresentational State Transfer (REST) is a key design idiom that embraces a stateless client-server architecture in which the web services are viewed as resources and can be identified by their URLs. Web service clients that want to use these resources access a particular representation by transferring application content using a small globally defined set of remote methods that describe the action to be performed on the resource. REST is an analytical description of the existing web architecture, and thus the interplay between the style and the underlying HTTP protocol appears seamless.

A RESTFul design may be appropriate when:

Page 92: Chapter

• The web services are completely stateless. A good test is to consider whether the interaction can survive a restart of the server.

• A caching infrastructure can be leveraged for performance. If the data that the web service returns is not dynamically generated and can be cached, then the caching infrastructure that web servers and other intermediaries inherently provide can be leveraged to improve performance. However, the developer must take care because such caches are limited to the HTTP GET method for most servers.

• The service producer and service consumer have a mutual understanding of the context and content being passed along. Because there is NO formal way to describe the web services interface, both parties must agree out of band on the schemas that describe the data being exchanged and on ways to process it meaningfully.

• Bandwidth is particularly important and needs to be limited. REST is particularly useful for limited-profile devices such as PDAs and mobile phones, for which the overhead of headers and additional layers of SOAP elements on the XML payload must be restricted.

• Web service delivery or aggregation into existing web sites can be enabled easily with a RESTful style. Developers can use technologies such as Asynchronous JavaScript with XML (Ajax) and toolkits such as Direct Web Remoting (DWR) to consume the services in their web applications. Rather than starting from scratch, services can be exposed with XML and consumed by HTML pages without significantly refactoring the existing web site architecture. Existing developers will be more productive because they are adding to something they are already familiar with, rather than having to start from scratch with new technology.

A SOAP-based design may be appropriate when:

• A formal contract must be established to describe the interface that the web service offers. The Web Services Description Language (WSDL) describes the details such as messages, operations, bindings, and location of the web service.

• The architecture must address complex nonfunctional requirements. Many web services specifications address such requirements and establish a common vocabulary for them. Examples include Transactions, Security, Addressing, Trust, Coordination, and so on. Most real-world applications go beyond simple CRUD operations and require contextual information and conversational state to be maintained. With the RESTful approach, developers must build this plumbing into the application layer themselves.

• The architecture needs to handle asynchronous processing and invocation. In such cases, the infrastructure provided by standards such as WSRM and APIs such as JAX-WS with their client-side asynchronous invocation support can be leveraged out of the box.

Describe the functions and capabilities of the APIs included within JAXP.

• [NONE] blah

The Java API for XML Processing (JAXP) is for processing XML data using applications written in the Java programming language. JAXP leverages the parser standards Simple API for XML Parsing (SAX) and Document Object Model (DOM) so that you can choose to parse your data as a stream of events or to build an object representation of it. JAXP also supports the Extensible Stylesheet Language Transformations (XSLT) standard, giving you control over the presentation of the data and enabling you to convert the data to other XML documents or to other formats, such as HTML. JAXP also provides namespace support, allowing you to work with DTDs that might otherwise have naming conflicts.

Streaming API for XML (StAX) provides is the latest API in the JAXP family.

The main JAXP APIs are defined in the javax.xml.parsers package. That package contains vendor-neutral factory classes -

SAXParserFactory,DocumentBuilderFactory, and TransformerFactory -which give you

a SAXParser, a DocumentBuilder, and an XSLT transformer, respectively. DocumentBuilder, in turn, creates a

DOM-compliant Document object.

The factory APIs let you plug in an XML implementation offered by another vendor without changing your source code. The implementation you get depends on the setting of

the javax.xml.parsers.SAXParserFactory, javax.xml.parsers.DocumentBuilderFactory, and javax.xml.transform.TransformerFactorysystem properties,

using System.setProperties() in the code, or -DpropertyName="..." on the command line. The default values (unless overridden at runtime on the command line or in the code) point to Sun's implementation.

The Simple API for XML (SAX) APIs

The basic outline of the SAX parsing APIs are shown below. To start the process, an instance of the SAXParserFactory class is used to generate an instance of the parser.

Page 93: Chapter

The parser wraps a SAXReader object. When the parser's parse() method is invoked, the reader invokes one of several callback methods implemented in the application. Those methods are defined by the

interfaces ContentHandler, ErrorHandler, DTDHandler, and EntityResolver.

Here is a summary of the key SAX APIs:

• SAXParserFactory

A SAXParserFactory object creates an instance of the parser determined by the system

property, javax.xml.parsers.SAXParserFactory.

• SAXParser

The SAXParser interface defines several kinds of parse() methods. In general, you pass an XML data source and

a DefaultHandler object to the parser, which processes the XML and invokes the appropriate methods in the handler object.

public static void main(String argv[]) { // Use an instance of ourselves as the SAX event handler DefaultHandler handler = new Echo(); // Use the default (non-validating) parser SAXParserFactory factory = SAXParserFactory.newInstance(); try { // Set up output stream out = new OutputStreamWriter(System.out, "UTF8"); // Parse the input SAXParser saxParser = factory.newSAXParser(); saxParser.parse(new File(argv[0]), handler); } catch (Throwable t) { t.printStackTrace(); } }

• SAXReader

Page 94: Chapter

The SAXParser wraps a SAXReader. Typically, you don't care about that, but every once in a while you need to get

hold of it using SAXParser'sgetXMLReader() so that you can configure it. It is the SAXReader that carries on the conversation with the SAX event handlers you define.

• DefaultHandler

Not shown in the diagram, a DefaultHandler implements

the ContentHandler, ErrorHandler, DTDHandler, and EntityResolver interfaces (with null methods), so you can override only the ones you're interested in.

• ContentHandler

Methods such as startDocument, endDocument, startElement, and endElement are invoked when an XML tag is recognized. This interface also defines the

methods characters and processingInstruction, which are invoked when the parser encounters the text in an XML element or an inline processing instruction, respectively.

• ErrorHandler

Methods error, fatalError, and warning are invoked in response to various parsing errors. The default error handler throws an exception for fatal errors and ignores other errors (including validation errors). That's one reason you need to know something about the SAX parser, even if you are using the DOM. Sometimes, the application may be able to recover from a validation error. Other times, it may need to generate an exception. To ensure the correct handling, you'll need to supply your own error handler to the parser.

• DTDHandler

Defines methods you will generally never be called upon to use. Used when processing a DTD to recognize and act on declarations for an unparsed entity.

• EntityResolver

The resolveEntity method is invoked when the parser must identify data identified by a URI. In most cases, a URI is simply a URL, which specifies the location of a document, but in some cases the document may be identified by a URN - a public identifier, or name, that is unique in the web space. The public identifier may be specified in addition to the URL.

The EntityResolver can then use the public identifier instead of the URL to find the document - for example, to access a local copy of the document if one exists.

A typical application implements most of the ContentHandler methods, at a minimum. Because the default implementations of the

interfaces ignore all inputs except for fatal errors, a robust implementation may also want to implement the ErrorHandler methods.

When to Use SAX

SAX is fast and efficient, but its event model makes it most useful for such state-independent filtering. For example, a SAX parser calls one method in your application when an element tag is encountered and calls a different method when text is found. If the processing you're doing is state-independent (meaning that it does not depend on the elements have come before), then SAX works fine.

On the other hand, for state-dependent processing, where the program needs to do one thing with the data under element A but something different with the data under element B, then a pull parser such as the Streaming API for XML (StAX) would be a better choice. With a pull parser, you get the next node, whatever it happens to be, at any point in the code that you ask for it. So it's easy to vary the way you process text (for example), because you can process it multiple places in the program.

SAX requires much less memory than DOM, because SAX does not construct an internal representation (tree structure) of the XML data, as a DOM does. Instead, SAX simply sends data to the application as it is read; your application can then do whatever it wants to do with the data it sees.

Pull parsers and the SAX API both act like a serial I/O stream. You see the data as it streams in, but you can't go back to an earlier position or leap ahead to a different position. In general, such parsers work well when you simply want to read data and have the application act on it.

But when you need to modify an XML structure - especially when you need to modify it interactively - an in-memory structure makes more sense. DOM is one such model. However, although DOM provides many powerful capabilities for large-scale documents (like books and articles), it also requires a lot of complex coding.

Page 95: Chapter

The Document Object Model (DOM) APIs

Figure below shows the DOM APIs in action:

You use the javax.xml.parsers.DocumentBuilderFactory class to get

a DocumentBuilder instance, and you use that instance to produce a Document object that conforms to the DOM specification. The builder you get, in fact, is determined by the system

property javax.xml.parsers.DocumentBuilderFactory, which selects the factory implementation that is used to produce the builder.

static Document document; public static void main(String argv[]) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); try { DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse( new File(argv[0]) ); } catch (SAXParseException spe) { ... } }

You can also use the DocumentBuilder.newDocument() method to create an empty Document that implements

the org.w3c.dom.Document interface. Alternatively, you can use one of the builder's parse methods to create

a Document from existing XML data.

public static void buildDom() { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); try { DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.newDocument(); Element root = (Element) document.createElement("rootElement"); document.appendChild(root); root.appendChild(document.createTextNode("Some")); root.appendChild(document.createTextNode(" ")); root.appendChild( document.createTextNode("text") ); } catch (ParserConfigurationException pce) { // Parser with specified options can't be built pce.printStackTrace(); } }

When to Use DOM

Page 96: Chapter

DOM is platform-neutral and language-neutral API that enables programs to dynamically update the contents of XML documents.

DOM creates an in-memory object representation of an entire XML document. This allows extreme flexibility in parsing, navigating, and updating the contents of a document. DOM's drawbacks are high memory requirements and the need for more powerful processing capabilities.

The Extensible Stylesheet Language Transformations (XSLT) APIs

Figure below shows the XSLT APIs in action:

A TransformerFactory object is instantiated and used to create a Transformer. The source object is the input to the transformation process. A source object can be created from a SAX reader, from a DOM, or from an input stream.

Similarly, the result object is the result of the transformation process. That object can be a SAX event handler, a DOM, or an output stream.

When the transformer is created, it can be created from a set of transformation instructions, in which case the specified transformations are carried out. If it is created without any specific instructions, then the transformer object simply copies the source to the result.

Here is a description of the packages that make up the JAXP Transformation APIs:

• javax.xml.transform

This package defines the factory class you use to get a Transformer object. You then configure the transformer with

input (source) and output (result) objects, and invoke its transform() method to make the transformation happen. The source and result objects are created using classes from one of the other three packages.

• javax.xml.transform.dom

Defines the DOMSource and DOMResult classes, which let you use a DOM as an input to or output from a transformation.

Document document; try { File f = new File(argv[0]); DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse(f); // Use a Transformer for output TransformerFactory tFactory = TransformerFactory.newInstance();

Page 97: Chapter

Transformer transformer = tFactory.newTransformer(); DOMSource source = new DOMSource(document); StreamResult result = new StreamResult(System.out); transformer.transform(source, result); }

• javax.xml.transform.sax

Defines the SAXSource and SAXResult classes, which let you use a SAX event generator as input to a transformation, or deliver SAX events as output to a SAX event processor.

public class AddressBookReader implements XMLReader {...} // Create the sax "parser" AddressBookReader saxReader = new AddressBookReader(); Transformer transformer = tFactory.newTransformer(); File f = new File(argv[0]); // Use the parser as a SAX source for input FileReader fr = new FileReader(f); BufferedReader br = new BufferedReader(fr); InputSource inputSource = new InputSource(br); SAXSource source = new SAXSource(saxReader, inputSource); StreamResult result = new StreamResult(System.out); transformer.transform(source, result);

• javax.xml.transform.stream

Defines the StreamSource and StreamResult classes, which let you use an I/O stream as an input to or output from a transformation.

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //factory.setNamespaceAware(true); //factory.setValidating(true); try { File stylesheet = new File(argv[0]); File datafile = new File(argv[1]); DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse(datafile); // Use a Transformer for output TransformerFactory tFactory = TransformerFactory.newInstance(); StreamSource stylesource = new StreamSource(stylesheet); Transformer transformer = tFactory.newTransformer(stylesource); DOMSource source = new DOMSource(document); StreamResult result = new StreamResult(System.out); transformer.transform(source, result); }

StAX API

The StAX API exposes methods for iterative, event-based processing of XML documents. XML documents are treated as a filtered series of events, and infoset states can be stored in a procedural fashion. Moreover, unlike SAX, the StAX API is bidirectional, meaning that it can both read and write XML documents.

The StAX API is really two distinct API sets: a cursor API and an iterator API.

• Cursor API

As the name implies, the StAX cursor API represents a cursor with which you can walk an XML document from beginning to end. This cursor can point to one thing at a time, and always moves forward, never backward, usually one infoset element at a time.

Page 98: Chapter

The two main cursor interfaces

are XMLStreamReader and XMLStreamWriter. XMLStreamReader includes accessor methods for all possible information retrievable from the XML Information model, including document encoding, element names, attributes, namespaces, text nodes, start tags, comments, processing instructions, document boundaries, and so forth; for example:

public interface XMLStreamReader { public int next() throws XMLStreamException; public boolean hasNext() throws XMLStreamException; public String getText(); public String getLocalName(); public String getNamespaceURI(); // ... other methods not shown }

A typical StAX program begins by using the XMLInputFactory class to load an implementation dependent instance

of XMLStreamReader:

URL u = new URL("http://www.example.com/data.xml"); InputStream in = u.openStream(); XMLInputFactory factory = XMLInputFactory.newInstance(); XMLStreamReader parser = factory.createXMLStreamReader(in);

The next() method in XMLStreamReader advances the cursor to the next item. Various getter methods to extract data from the current item. Some of the most important of these getters

include: getName(), getLocalName(), getText(), etc.

For example, here's a simple bit of code that iterates through an XML document and prints out the names of the different elements it encounters:

while (true) { int event = parser.next(); if (event == XMLStreamConstants.END_DOCUMENT) { parser.close(); break; } if (event == XMLStreamConstants.START_ELEMENT) { System.out.println(parser.getLocalName()); } }

You can call methods on XMLStreamReader, such as getText and getName, to get data at the current

cursor location. XMLStreamWriter provides methods that correspond

to StartElement and EndElement event types; for example:

public interface XMLStreamWriter { public void writeStartElement(String localName) throws XMLStreamException; public void writeEndElement() throws XMLStreamException; public void writeCharacters(String text) throws XMLStreamException; // ... other methods not shown }

This interface provides methods to write elements, attributes, comments, text, and all the other parts of an XML document.

An XMLStreamWriter is created by an XMLOutputFactory like this:

OutputStream out = new FileOutputStream("data.xml"); XMLOutputFactory factory = XMLOutputFactory.newInstance(); XMLStreamWriter writer = factory.createXMLStreamWriter(out);

You write data onto the stream by using

various writeXXX methods: writeStartDocument, writeStartElement, writeEndElement, writeCharacters,writeComment, writeCDATA, etc. For example, these lines of code write a simple document:

Page 99: Chapter

writer.writeStartDocument("ISO-8859-1", "1.0"); writer.writeStartElement("greeting"); writer.writeAttribute("id", "g1"); writer.writeCharacters("Hello StAX"); writer.writeEndDocument();

The cursor API mirrors SAX in many ways. For example, methods are available for directly accessing string and character information, and integer indexes can be used to access attribute and namespace information. As with SAX, the cursor API methods return XML information as strings, which minimizes object allocation requirements.

• Iterator API

The StAX iterator API represents an XML document stream as a set of discrete event objects. These events are pulled by the application and provided by the parser in the order in which they are read in the source XML document.

The base iterator interface is called XMLEvent, and there are subinterfaces for each event type

(StartDocument, StartElement, EndElement, etc.). The primary parser interface for reading iterator

events is XMLEventReader, and the primary interface for writing iterator events is XMLEventWriter.

TheXMLEventReader interface contains five methods, the most important of which is nextEvent(), which

returns the next event in an XML stream.XMLEventReader extends java.util.Iterator, which means

that returns from XMLEventReader can be cached or passed into routines that can work with the standard

Java Iterator; for example:

public interface XMLEventReader extends Iterator { public XMLEvent nextEvent() throws XMLStreamException; public boolean hasNext(); public XMLEvent peek() throws XMLStreamException; // ... other methods not shown }

Similarly, on the output side of the iterator API, you have:

public interface XMLEventWriter { public void flush() throws XMLStreamException; public void close() throws XMLStreamException; public void add(XMLEvent e) throws XMLStreamException; public void add(Attribute attribute) throws XMLStreamException; // ... other methods not shown }

Comparing Cursor and Iterator APIs

Before choosing between the cursor and iterator APIs, you should note a few things that you can do with the iterator API that you cannot do with cursor API:

• Objects created from the XMLEvent subclasses are immutable, and can be used in arrays, lists, and maps, and can be passed through your applications even after the parser has moved on to subsequent events.

• You can create subtypes of XMLEvent that are either completely new information items or extensions of existing items but with additional methods.

• You can add and remove events from an XML event stream in much simpler ways than with the cursor API.

Similarly, keep some general recommendations in mind when making your choice:

• If you are programming for a particularly memory-constrained environment, like J2ME, you can make smaller, more efficient code with the cursor API.

• If performance is your highest priority - for example, when creating low-level libraries or infrastructure - the cursor API is more efficient.

• If you want to create XML processing pipelines, use the iterator API.

• If you want to modify the event stream, use the iterator API.

• If you want to your application to be able to handle pluggable processing of the event stream, use the iterator API.

Page 100: Chapter

• In general, if you do not have a strong preference one way or the other, using the iterator API is recommended because it is more flexible and extensible, thereby "future-proofing" your applications.

When to Use StAX

StAX's bidirectional features, small memory footprint, and low processor requirements give it an advantage over APIs such as JAXB or DOM. StAX is particularly effective in extracting a small set of information from a large document. The primary drawback in using StAX is that you get a narrow view of the document - essentially you have to know what processing you will do before reading the XML document. Another drawback is that StAX is difficult to use if you return XML documents that follow complex schema.

Chapter 6. JAXR

Describe the function of JAXR in Web service architectural model, the two basic levels of business registry functionality supported by JAXR, and the function of the basic JAXR business objects and how they map to the UDDI data structures.

• [NONE] blah

JAXR, the Java API for XML Registries, provides a standard API for publication and discovery of Web services through underlying registries.

JAXR does not define a new registry standard. Instead, this standard Java API performs registry operations over a diverse set of registries and defines a unified information model for describing registry contents. Regardless of the registry provider accessed, your programs use common APIs and a common information model. The JAXR specification defines a general-purpose API, allowing any JAXR client to access and interoperate with any business registry accessible via a JAXR provider.

Capability profiles

Because some diversity exists among registry provider capabilities, the JAXR expert group decided to provide multilayer API abstractions through capability profiles. Each method of a JAXR interface is assigned a capability level, and those JAXR methods with the same capability level define the JAXR provider capability profile.

Currently, JAXR defines only two capability profiles: level 0 profile for basic features and level 1 profile for advanced features. Level 0's basic features support so-called business-focused APIs, while level 1's advanced features support generic APIs. At the minimum, all JAXR providers must implement a level 0 profile. A JAXR client application using only those methods of the level 0 profile can access any JAXR provider in a portable manner. JAXR providers for UDDI must be level 0 compliant.

JAXR providers can optionally support the level 1 profile. The methods assigned to this profile provide more advanced registry capabilities needed by more demanding JAXR clients. Support for the level 1 profile also implies full support for the level 0 profile. JAXR providers for ebXML must be level 1 compliant. A JAXR client can discover the capability level of a JAXR provider by invoking methods on

the CapabilityProfile interface. If the client attempts to invoke capability level methods unsupported by the JAXR provider,

the provider will throw an UnsupportedCapabilityException.

When publication or discovery of Web services is required, UDDI is the mechanism the WS-I Basic Profile has adopted to describe Web service providers and the Web services they provide.

NOTE, because WS-I BP sanctions the use of UDDI, not ebXML, we MUST use JAXR level 0 profile.

RegistryService interfaces

The JAXR provider supports capability profiles that group the methods on JAXR interfaces by capability

level. RegistryService exposes the JAXR provider's key interfaces, that is, Web services discovery and registration. The JAXR

client can obtain an instance of the RegistryService interface by invoking thegetRegistryService() method on

the connection established between the JAXR client and JAXR provider. Once the JAXR client has the RegistryService, it can obtain the primary registry interfaces and perform life-cycle management and query management through the JAXR provider.

The JAXR specification defines two life-cycle management interfaces:

1. BusinessLifeCycleManager - for level 0 (we MUST use this interface according to WS-I BP 1.1)

2. LifeCycleManager - for level 1 (we MUST NOT use this interface according to WS-I BP 1.1)

Page 101: Chapter

BusinessLifeCycleManager defines a simple business-level API for life-cycle management. This interface resembles the

publisher's API in UDDI, which should prove familiar to the UDDI developer. For its part, LifeCycleManager interface provides complete support for all life-cycle management needs using a generic API.

Life-cycle management includes creating, saving, updating, deprecating, and deleting registry objects. In addition,

the LifeCycleManager provides several factory methods to create JAXR information model objects. In general, life-cycle management operations are privileged, while a user can use query management operations for browsing the registry.

JAXR's top-level interface for query management, QueryManager, has two extensions:

1. BusinessQueryManager - for level 0 (we MUST use this interface according to WS-I BP 1.1)

2. DeclarativeQueryManager - for level 1 (we MUST NOT use this interface according to WS-I BP 1.1)

Query management deals with querying the registry for registry data. A simple business-level API,

the BusinessQueryManager interface provides the ability to query for the most important high-level interfaces in the

information model, such as Organization, Service, ServiceBinding, ClassificationScheme,

andConcept. Alternatively, the DeclarativeQueryManager interface provides a more flexible, generic API, enabling the JAXR client to perform ad hoc queries using a declarative query language syntax. Currently, the only declarative syntaxes JAXR supports are SQL-92 and OASIS/ebXML Registry Filter Queries. As noted in the JAXR specification, ebXML registry providers optionally support SQL queries. If a registry provider does support SQL queries, the JAXR ebXML provider will throw

an UnsupportedCapabilityException on DeclarativeQueryManager methods.

JAXR information model

Invoking life-cycle and query management methods on the JAXR provider requires the JAXR client to create and use the JAXR information model objects. The JAXR information model resembles the one defined in the ebXML Registry Information Model 2.0, but also accommodates the data types defined in the UDDI Data Structure Specification. Although developers familiar with the UDDI information model might face a slight learning curve, once understood, the JAXR information model will provide a more intuitive and natural interface to most developers.

Most JAXR information-model interfaces are derived from the abstract RegistryObject interface, which defines the common state

information, called attributes, that all registry objects share. Example attributes include: key, name, and description.

The InternationalString interface defines attributes that must be internationalization compatible, such

as name and description. The InternationalString interface contains a collection

of LocalizedStrings, where each LocalizedString defines locale, character set, and string content.

The RegistryObject interface also defines collections

of Classification, ExternalIdentifier, ExternalLink, and Association objects.

TheBusinessQueryManager often uses those collections as parameters in its find methods.

Also specializations of the RegistryObject interface, the concrete

interfaces Organization, Service, ServiceBinding, Concept,

and ClassificationSchemeprovide additional state information. For example, the Organization interface defines a

collection of Service objects, and Service defines a collection ofServiceBinding objects.

A ServiceBinding might contain a collection of SpecificationLink objects. UDDI developers should be familiar with these concrete interfaces; they map quite well to major UDDI data types shown in the table below:

Table 6.1. UDDI-to-JAXR information model mappings

JAXR Information Model UDDI Data Model

Organization

A business, such as a corporation whose data is contained in the registry, is represented

by an Organization instance. An Organization can have

multiple Organizations under it or can refer to another organization as a

parent. An Organization can offer one or more services, represented

byService objects which can be accessed via Collection Organization.getServices() method.

businessEntity

The businessEntity structure contains information about a

particular business organization and holds references to the services it

offers.businessEntity is the highest in the hierarchy and

contains descriptive information. Each businessEntity is

identified by its businessKey. If itsbusinessKey is not

specified at publication time, the registry will automatically generate a key.

Page 102: Chapter

JAXR Information Model UDDI Data Model

Service

Each Service can have multiple ServiceBinding objects that specify

the details about the protocol binding information for that service.

businessService

businessService entry indicates a logical service and holds

descriptive information about a Web service in business terms.

A businessService is a child of

a businessEntity that provides the service. Information about

how a businessService can be instantiated is contained within

abindingTemplate. Each businessService is

has a unique identifier -serviceKey. This value is assigned by each

UDDI operator and cannot be edited by the publisher. It also contains the key

to its parentbusinessEntity - businessKey.

ServiceBinding

ServiceBinding has attributes that describe the location where the service

can be accessed. A ServiceBinding is associated with one or

more SpecificationLink objects that point to the technical

specifications defining the service (e.g., a WSDL file for the Web

service).ServiceBinding instances

are RegistryObject objects that represent technical information on a

specific way to access a specific interface offered by a Service instance.

A ServiceBinding may have a set

ofSpecificationLink instances. Maps to

a bindingTemplate in UDDI.

bindingTemplate

A bindingTemplate contains information necessary for a client

to invoke a service. It specifies the information for a particular Web service and provides the URL of the service where it can be invoked.

ThebindingTemplate also contains references to tModels

as well as service-specific settings. A bindingTemplate is a

child of a businessService.

ClassificationScheme

A ClassificationScheme instance represents a taxonomy that may

be used to classify or categorize RegistryObject instances. The

classification scheme, or taxonomy, can be internal or external to the registry, meaning that the structure of the taxonomy is defined internal to the registry or is represented somewhere outside the registry and is represented by

aClassificationScheme interface. A good example of an external

taxonomy for e-business is that of North American Industry Classification System (NAICS) devised by the U.S. Census Bureau. NAICS is a classification scheme used to classify businesses and services by the industry to which they belong and the business processes they follow. tModel

Concept

The Concept interface is used to represent taxonomy elements and their structural

relationship with each other in order to describe an internal

taxonomy. Concept instances are used to define tree structures where the root of

the tree is a ClassificationScheme instance and each node in the

tree is a Concept instance. As any RegistryObject,

a Concept may be classified and also associated with a set of external identifiers

and links.

Association

A RegistryObject instance may be associated with zero or

moreRegistryObject instances. The information model defines

anAssociation interface, an instance of which may be used to associate any

two RegistryObject instances. An Association instance

represents an association between a source RegistryObject and a

targetRegistryObject. These are referred to

as sourceObject andtargetObject for

the Association instance. It is important which object is

the sourceObject and which is the targetObject as it

publisherAssertion

Page 103: Chapter

JAXR Information Model UDDI Data Model

determines the directional semantics of an Association.

Each Association must have an associationType attribute

that identifies the type of that association. The associationType attribute

is a reference to an enumeration Conceptas defined by the

predefined associationType ClassificationScheme in

the JAXR specification. An association may need to be confirmed by the parties whose

objects are involved in that Association.

ExternalLink

ExternalLink instances model a named URI to content that may reside

outside the registry. RegistryObject may be associated with any number

of ExternalLink instances to annotate a RegistryObject with

external links to external content. Consider the case where a Submitting Organization submits a repository item (e.g. a DTD) and wants to associate some external content to that object (e.g. the Submitting Organization's home page).

The ExternalLink enables this capability.

overviewDoc

Classification

The Classification interface is used to

classify RegistryObjectinstances. A RegistryObject may be

classified along multiple dimensions by adding zero or

more Classification instances to theRegistryObject. For

example, an Organization may be classified by its industry, by the products

it sells and by its geographical location. In this example

the RegistryObject would have at least

three Classificationinstances added to it.

The RegistryObject interface provides

severaladdClassification methods to allow a client to

add Classificationinstances to a RegistryObject.

keyedReference (in categoryBag)

ExternalIdentifier

ExternalIdentifier instances provide the additional identifier

information to RegistryObject such as DUNS number, Social Security

Number, or an alias name of the organization. The attribute name inherited

from RegistryObject is used to contain the identification scheme (Social

Security Number, etc), and the attribute value contains the actual information.

Each RegistryObjects may have 0 or more association(s)

with ExternalIdentifier.

keyedReference (in identifierBag)

User contact

Collection of ExternalIdentifier instances identifierBag

Collection of Classification instances categoryBag

PostalAddress address

SpecificationLink

A SpecificationLink provides the linkage between

a ServiceBindingand one of its technical specifications that describes how

to use the service using the ServiceBinding. For example,

a ServiceBinding may have

aSpecificationLink instance that describes how to access the service

using a technical specification in form of a WSDL document. It serves the same purpose as the union

The union

of tModelInstanceInfo and instanceDetails

Page 104: Chapter

JAXR Information Model UDDI Data Model

of tModelInstanceInfo andinstanceDetails in UDDI.

UDDI Example Mapped to JAXR:

Page 105: Chapter

Table 6.2. Mapping of UDDI Inquiry API Calls To JAXR (BusinessQueryManager)

UDDI Method BusinessQueryManager Method

find_binding findServiceBindings

find_business findOrganizations

find_related_business findAssociatedObjects(RegistryObject, asociationType)

find_service findServices

find_tModel findConcepts, findClassificationSchemes

get_bindingDetail Not needed. Handled transparently by JAXR provider

Page 106: Chapter

UDDI Method BusinessQueryManager Method

get_businessDetail Not needed. Handled transparently by JAXR provider

get_businessDetailExt Unsupported.

Use RegistryService.makeRegistrySpecificRequest

get _serviceDetail Not needed. Handled transparently by JAXR provider

get_tModelDetail Not needed. Handled transparently by JAXR provider

Table 6.3. Mapping of UDDI Publisher API Calls to JAXR (BusinessLifeCycleManager)

UDDI Method BusinessLifeCycleManager Method

add_publisherAssertions saveAssociations(associations, replace), Association.confirm

delete_binding deleteServiceBindings

delete_business deleteOrganizations

delete_publisherAssertions deleteAssociations

delete_service deleteServices

delete_tModel

deleteClassificationsSchemes, deleteConcepts.

NOTE, In UDDI delete_tModel does not delete the tModel. It simply hides it

from find_tModel calls.

The QueryManager.getRegistryObjectcalls will still return the

deleted tModel after

a deleteConcepts ordeleteClassificationSchemes call.

discard_authToken Not needed. Handled transparently by JAXR provider

get_assertionStatusReport

findAssociations(findQulifiers, associationTypes, sourceObjectConfirmed, targetObjectConfirmed)

get_authToken Not needed. Handled transparently by JAXR provider

get_publisherAssertions QueryManager.getRegistryObjects(objectType)

get_registeredInfo QueryManager.getRegistryObjects

save_binding saveServiceBindings

save_business saveOrganizations

save_service saveServices

save_tModel saveClassificationsSchemes, saveConcepts

set_publisherAssertions saveAssociations(assiations,replace)

The JAXR specification defines the following information model interfaces:

Page 107: Chapter

• Organization instance is a RegistryObject that provides information on an organization that has been published to the underlying registry.

• Service instance is a RegistryObject that provides information on services (e.g., Web Service) offered by

an Organization. An Organization can have a set of Service objects.

• ServiceBinding instance is a RegistryObject that represents technical information on how to access a

specific interface offered by a Serviceinstance. A Service can have a collection of ServiceBinding objects.

• SpecificationLink links a ServiceBinding with its technical specifications that describe how to use the

service. For example, a ServiceBinding might have SpecificationLink instances that describe how to access the service using a technical specification in the form of a WSDL (Web Services Description Language) document.

• ClassificationScheme instance represents a taxonomy that you can use to classify or

categorize RegistryObject instances.

• Classification instances classify a RegistryObject instance using a classification scheme. Because

classification facilitates rapid discovery ofRegistryObject instances within the registry, the ability to

classify RegistryObject instances in a registry is one of the registry's most significant features.

• Concept instance represents an arbitrary notion, or concept. It can be virtually anything.

• Association instances define many-to-many associations between objects in the information model.

• RegistryPackage instances group together logically related RegistryObject instances.

A RegistryPackage might contain any number ofRegistryObject instances, and

a RegistryObject can be a member of any number of RegistryPackage objects.

• ExternalIdentifier instances provide identification information to a RegistryObject. You can base such identification on well-known identification schemes such as DUNS (D&B's Data Universal Numbering System) number and social security number.

• ExternalLink instances provide a link to content managed outside the registry using a URI (uniform resource identifier).

• Slot instances dynamically add arbitrary attributes to RegistryObject instances at runtime, an ability that enables extensibility within the information model.

• Most interfaces in the JAXR information model extend the ExtensibleObject interface. It provides methods that

allow the addition, deletion, and lookup of Slot instances.

• AuditableEvent instances are RegistryObject instances that provide an audit trail

for RegistryObject instances.

• Affiliated with Organization, User objects are RegistryObject instances that provide information about

registered users within the registry. You useUser objects in a RegistryObject's audit trail.

• PostalAddress defines a postal address's attributes. Currently, it provides address information for a User and

an Organization.

Create JAXR client to connect to a UDDI business registry, execute queries to locate services that meet specific requirements, and publish or update information about a business service.

• [NONE] blah

Establish a connection between a JAXR client and JAXR provider

The JAXR client must first connect to the JAXR provider. This connection contains the client state and preference information used when the JAXR provider invokes methods on the registry provider.

Before executing any registry operation, a JAXR client connects with a JAXR provider as shown in the following code:

import javax.xml.registry.*; ... // Get an instance of ConnectionFactory object ConnectionFactory connFactory = ConnectionFactory.newInstance(); // Define connection configuration properties // Set URLs of the query service and publishing service Properties props = new Properties();

Page 108: Chapter

props.setProperty("javax.xml.registry.queryManagerURL", "http://uddi.ibm.com/testregistry/inquiryapi"); props.setProperty("javax.xml.registry.lifeCycleManagerURL", "https://uddi.ibm.com/testregistry/protect/publishapi"); // If JAXR client goes outside firewall for query, set up HTTP proxy props.setProperty("com.sun.xml.registry.http.proxyHost", "myhost.mydomain"); props.setProperty("com.sun.xml.registry.http.proxyPort", "8080"); // If JAXR client goes outside firewall for update, set up HTTPS proxy props.setProperty("com.sun.xml.registry.https.proxyHost", "myhost.mydomain"); props.setProperty("com.sun.xml.registry.https.proxyPort", "8080"); // Set up properties and create Connection object connFactory.setProperties(props); Connection connection = connFactory.createConnection();

If the JAXR client wishes to submit data to the registry, the client must set authentication information on the connection. Note that the establishment of this authentication information with the registry provider is registry-provider specific and negotiated between the registry provider and the publishing user, often in the form of a Web-based interface. The user does not use the JAXR API to negotiate and establish

an account with the registry provider. After establishing a connection, the JAXR client can obtain RegistryService interfaces for Web Services discovery and publishing:

// Get RegistryService object RegistryService rs = connection.getRegistryService(); // Get QueryManager and LifeCycleManager objects for // JAXR Business API (Capability Level 0 - UDDI oriented) BusinessQueryManager bqm = rs.getBusinessQueryManager(); BusinessLifeCycleManager blcm = rs.getBusinessLifeCycleManager();

This example also demonstrates how to obtain the business-focused interfaces, the BusinessLifeCycleManager and

the BusinessQueryManager, to perform registry operations shown in later examples:

/* * Establish a connection to a JAXR provider. * Set authentication information, communication preference. * Get business-focused discovery and publish interfaces. */ public void makeConnection() { // URLs for RegistryServer String queryURL = "http://localhost/RegistryServerServlet"; String publishURL = "http://localhost/RegistryServerServlet"; /* * Define connection configuration properties. * For simple queries, you need the query URL. * To use a life-cycle manager, you need the publish URL. */ Properties props = new Properties(); props.setProperty("javax.xml.registry.queryManagerURL", queryUrl); props.setProperty("javax.xml.registry.lifeCycleManagerURL", publishUrl); try { // Create the connection, passing it the configuration properties ConnectionFactory factory = ConnectionFactory.newInstance(); factory.setProperties(props); connection = factory.createConnection(); System.out.println("Created connection to registry"); // Get registry service and managers RegistryService rs = connection.getRegistryService(); // Get the capability profile CapabilityProfile capabilityProfile = registryService.getCapabilityProfile(); if (capabilityProfile.getCapabilityLevel() == 0) { System.out.println("Capability Level 0, Business Focused API"); } // Get manager capabilities from registry service BusinessQueryManager bqm = rs.getBusinessQueryManager(); BusinessLifeCycleManager blcm = rs.getBusinessLifeCycleManager(); System.out.println("Got registry service, query manager and lifecycle manager"); // Set client authorization information for privileged registry operations PasswordAuthentication passwdAuth = new PasswordAuthentication(username, password.toCharArray()); Set creds = new HashSet(); creds.add(passwdAuth); // Set credentials on the JAXR provider connection.setCredentials(creds); System.out.println("Established security credentials"); // Set communication preference connection.setSynchronous(true);

Page 109: Chapter

} catch (Exception e) { e.printStackTrace(); if (connection != null) { try { connection.close(); } catch (JAXRException je) { } } } }

Registry operation: execute queries to locate services

Now that the JAXR client has established a connection with the JAXR provider and obtained

the BusinessQueryManager and BusinessLifeCycleManager from

the RegistryService interface, the client can now invoke methods on these interfaces. Often, a JAXR client will wish to discover

the services an organization offers. To do so, the JAXR client would invoke methods on the BusinessQueryManager.

JAXR defines top-level interface for query management called QueryManager. There are two extensions

of QueryManager interface and they are

calledBusinessQueryManager and DeclarativeQueryManager.

Interface BusinessQueryManager provides a simple business-level API that provides the ability to query for the most important high-level interfaces in the information model.

Interface DeclarativeQueryManager provides a more flexible generic API that provides the ability to perform ad hoc queries using a declarative query language syntax. Currently the only declarative syntax supported is SQL-92. In version 1 of JAXR, it is optional for a JAXR provider to provide support for SQL query syntax.

This example shows how to find all the organizations in the registry whose names begin with a specified string, qString, and to sort them in alphabetical order:

// Define find qualifiers. Sort by name. Collection findQualifiers = new ArrayList(); findQualifiers.add(FindQualifier.SORT_BY_NAME_DESC); // Define name patterns. Organization name begins with qString. Collection namePatterns = new ArrayList(); namePatterns.add(qString); // Find organizations using the name BulkResponse response = bqm.findOrganizations(findQualifiers, namePatterns, null, null, null, null); Collection orgs = response.getCollection();

Another example shows how to find all the organizations in the registry using case sensitive name pattern:

// Define find qualifiers. Do case sensitive search. Collection findQualifiers = new ArrayList(); findQualifiers.add(FindQualifier.CASE_SENSITIVE_MATCH); // Define name patterns. Organization name contains qString. Collection namePatterns = new ArrayList(); namePatterns.add("%" + qString + "%"); // Find organizations using the name BulkResponse response = bqm.findOrganizations(findQualifiers, namePatterns, null, null, null, null); Collection orgs = response.getCollection();

Steps for finding Organization by Classification:

1. Decide on classification scheme (taxonomy). 2. Build a classification within a particular classification scheme.

3. Specify the classification as an argument to the findOrganizations method.

Page 110: Chapter

To find organizations by classification, you need to establish the classification within a particular classification scheme and then specify the

classification as an argument to the findOrganizations method. The following code fragment finds all organizations that correspond to a particular classification within the North American Industry Classification System (NAICS) taxonomy:

// Get classification scheme. Taxonomy is NAICS. ClassificationScheme cScheme = bqm.findClassificationSchemeByName(null, "ntis-gov:naics"); // Build classifications Classification classification = blcm.createClassification(cScheme, "Snack and Nonalcoholic Beverage Bars", "722213"); Collection classifications = new ArrayList(); classifications.add(classification); // Find organizations via Classification BulkResponse response = bqm.findOrganizations(null, null, classifications, null, null, null); Collection orgs = response.getCollection();

To find WSDL Specification Instances: use classification scheme of "uddi-org:types". In JAXR, a concept is used to hold information about a WSDL specification. JAXR client must find the specification concepts first, then the organizations that use those concepts.

Once you get organizations, you can then get services and bindingTemplates:

// Get classification scheme. Taxonomy is uddi-org:types. String schemeName = "uddi-org:types"; ClassificationScheme uddiOrgTypes = bqm.findClassificationSchemeByName(null, schemeName); // Create a classification, specifying the scheme // and the taxonomy name and value defined for WSDL // documents by the UDDI specification. Classification wsdlSpecClassification = blcm.createClassification(uddiOrgTypes, "wsdlSpec", "wsdlSpec"); Collection classifications = new ArrayList(); classifications.add(wsdlSpecClassification); // Find concepts BulkResponse br = bqm.findConcepts(null, null, classifications, null, null); // Display information about the concepts found Collection specConcepts = br.getCollection(); Iterator iter = specConcepts.iterator(); if (!iter.hasNext()) { System.out.println("No WSDL specification concepts found"); } else { while (iter.hasNext()) { Concept concept = (Concept) iter.next(); String name = getName(concept); Collection links = concept.getExternalLinks(); System.out.println("Specification Concept: Name: " + name + "Key: " + concept.getKey().getId() + "Description: " + getDescription(concept)); if (links.size() > 0) { ExternalLink link = (ExternalLink) links.iterator().next(); System.out.println("URL of WSDL document: '" + link.getExternalURI() + "'"); } // Find organizations that use this concept Collection specConcepts1 = new ArrayList(); specConcepts1.add(concept); br = bqm.findOrganizations(null, null, null, specConcepts1, null, null); // Display information about organizations ... } }

Finding Services and Service Bindings from Organization:

Iterator orgIter = orgs.iterator(); while (orgIter.hasNext()) { Organization org = (Organization) orgIter.next(); Collection services = org.getServices(); Iterator svcIter = services.iterator(); while (svcIter.hasNext()) { Service svc = (Service) svcIter.next(); Collection serviceBindings = svc.getServiceBindings(); Iterator sbIter = serviceBindings.iterator(); while (sbIter.hasNext()) { ServiceBinding sb = (ServiceBinding) sbIter.next(); }

Page 111: Chapter

} }

Another example use case might be the following:

A user browsing the UDDI registry wishes to find an organization that provides services of the NAICS (North American Industry Classification System) type Computer Systems Design and Related Services in the United States. To perform this query with JAXR, the user would invoke

a findOrganization() method with classification listed under the well-known taxonomies NAICS and ISO 3166 Geographic Code System (ISO 3166). As JAXR provides a taxonomy service for these classifications, the client can easily access the classification

information needed to be passed as findOrganization() parameters. A sample of this query to the taxonomy service and registry follows below:

public void findOrganizations() throws JAXRException { // Search criteria -- Organizations found will return in this sort order Collection findQualifiers = new ArrayList(); findQualifiers.add(FindQualifier.SORT_BY_NAME_DESC); // Query the JAXR taxonomy service ClassificationScheme naics = businessQueryManager.findClassificationSchemeByName( findQualifiers, "ntis-gov:naics:1997"); // Create the classification that will be a parameter to findOrganization() method Classification computerSystemsDesign = businessLifeCycleManager.createClassification( naics, "Computer Systems Design and Related Services", "5415"); // Query the taxonomy service ClassificationScheme geography = businessQueryManager.findClassificationSchemeByName( findQualifiers, "iso-ch:3166:1999"); // Create the classification passed as a parameter to findOrganization() method. Classification us = businessLifeCycleManager.createClassification( geography, "United States", "US"); // Add classifications to the classifications collection parameter Collection classifications = new ArrayList(); classifications.add(computerSystemsDesign); classifications.add(us); // Invoke the findOrganizations() method on BusinessQueryManager BulkResponse bulkResponse = businessQueryManager.findOrganizations( findQualifiers, null, classifications, null, null, null); if (bulkResponse.getStatus() == JAXRResponse.STATUS_SUCCESS) { System.out.println("Found Organization located in the United States "); System.out.println("categorized Computer Systems Design and Related Service "); } }

Most calls invoked on the registry provider via the JAXR provider return a BulkResponse that contains any registry exceptions

encountered and a collection of concrete RegistryObject instances or RegistryObject keys. To ensure that a registry invocation always returns a response, any exceptions generated by the registry provider are wrapped in

a RegistryException and stored in the BulkResponse's exceptions collection. In the case

of findXXX(...) methods, anyRegistryObjects found are contained in the BulkResponse collection.

For the above findOrganization() method, the BulkResponse contains a collection

of Organization objects found in the registry provider that match the classifications passed as parameters to the method. However,

these Organization objects provide limited information about the Organization and itsService objects such

as key, name, and description. Another value-added feature of JAXR is the incremental loading

of RegistryObject details. For instance, in the case of a JAXR UDDI provider, a JAXR findOrganization() method

transforms to a UDDI find_Business request. After invocation, the find_Businessrequest returns minimal business and service information such as ID, name, and description. Using UDDI APIs, a UDDI client would need to make an additional call such

as get_BusinessDetail() to retrieve the organization details. With JAXR, the JAXR UDDI provider performs this invocation to

the registry provider on an as-needed basis. The JAXR client can access Organization and other RegistryObject details

by using the getXXX() methods on the JAXR information model interfaces. The getOrganizationDetail() method

demonstrates how a JAXR client would obtain full Organization details:

public void getOrganizationDetail(BulkResponse bulkResponse) throws JAXRException {

Page 112: Chapter

// Get a collection of Organizations from BulkResponse Collection organizations = bulkResponse.getCollection(); // Iterate through the collection to get an individual Organization Iterator orgIter = organizations.iterator(); while (orgIter.hasNext()) { Organization organization = (Organization) orgIter.next(); // Get a collection of Services from an Organization Collection services = organization.getServices(); // Iterate through the collection to get an individual Service Iterator serviceIter = services.iterator(); while (serviceIter.hasNext()) { Service service = (Service) serviceIter.next(); // Get a collection of ServiceBindings from a Service Collection serviceBindings = service.getServiceBindings(); // Iterate through the collection to get an individual ServiceBinding Iterator sbIter = serviceBindings.iterator(); while (sbIter.hasNext()) { ServiceBinding serviceBinding = (ServiceBinding) sbIter.next(); // Get URI of the service. You can access the service through this URI. String accessURI = serviceBinding.getAccessURI(); System.out.println("Access the service " + service.getName().getValue() + " at this URI " + accessURI); // Get a collection of SpecificationLinks from a ServiceBinding. // SpecificationLinks provide further technical details needed to access the service. Collection specificationLinks = serviceBinding.getSpecificationLinks(); // Iterate through the collection to get an individual SpecificationLink Iterator linkIter = specificationLinks.iterator(); while (linkIter.hasNext()) { SpecificationLink specificationLink = (SpecificationLink) linkIter.next(); // Get a collection of ExternalLinks from SpecificationLink // An ExternalLink points to technical detail necessary to invoke the service Collection externalLinks = specificationLink.getExternalLinks(); // Iterate through the collection to get an ExternalLink Iterator elinkIter = externalLinks.iterator(); while (elinkIter.hasNext()) { ExternalLink externalLink = (ExternalLink) elinkIter.next(); // The externalURI is the pointer to the technical details // necessary to invoke the service String externalURI = externalLink.getExternalURI(); System.out.println( " Use the technical detail at this URI, " + externalURI + " to invoke the service, " + + service.getName().getValue()); } // Obtain usage description InternationalString usageDescription = specificationLink.getUsageDescription(); // Any parameters necessary to invoke service are in usageParameter collection Collection usageParameters = specificationLink.getUsageParameters(); // Get the specification concept from the specification link // This specificationConcept is equivalent to the tModel registered as // the technical specification Concept specificationConcept = (Concept) specificationLink.getSpecificationObject(); } } } } }

Registry operation: publish or update information about a business service

The JAXR client also publishes Web services, another important registry operation. In addition to discovering partner organization information and services, an organization will want to register its information and services in the registry for partner use. If a JAXR client wishes to

publish an organization and its services to a registry, the client uses the LifeCycleManager or the more

focused BusinessLifeCycleManager. Clients familiar with UDDI should use

Page 113: Chapter

theBusinessLifeCycleManager, which provides methods for saving information to the registry provider. Since this is a privileged operation, the user must set authentication information on the JAXR connection. Note that the JAXR provider, not the JAXR client, performs authentication with the registry provider. The JAXR provider negotiates this authentication with the registry provider on an as-needed basis, and the authentication is completely transparent to the JAXR client.

JAXR specification defines two interfaces – LifeCycleManager interface

and BusinessLifeCycleManager interface. LifeCycleManager interface provides complete support for all life

cycle management needs using a generic API. BusinessLifeCycleManager interface defines a simple business-level API for life cycle management of some important high-level interfaces in the information model. This interface provides no new functionality

beyond that ofLifeCycleManager. The goal of defining this interface is to provide an API similar to that of the publisher’s API in UDDI. The intent is to provide a familiar API to UDDI developers.

Before it can submit data, the client must send its username and password to the registry in a set of credentials. The following code fragment shows how to do this:

// Set userid/password String username = "myUserName"; String password = "myPassword"; // Create authentication object PasswordAuthentication passwdAuth = new PasswordAuthentication(username, password.toCharArray()); // Set the credential with registry provider Set creds = new HashSet(); creds.add(passwdAuth); connection.setCredentials(creds);

The client creates the organization and populates it with data before saving it. An Organization object is one of the more complex data items in the JAXR API. It normally includes the following:

1. A Name object.

2. A Description object.

3. A Key object, representing the ID by which the organization is known to the registry.

4. A PrimaryContact object, which is a User object that refers to an authorized user of the registry. A User object

normally includes a PersonName object and collections

of TelephoneNumber and EmailAddress objects.

5. A collection of Classification objects.

6. Service objects and their associated ServiceBinding objects.

Creating an Organization:

// Create organization name and description Organization org = blcm.createOrganization("The Coffee Break"); InternationalString s = blcm.createInternationalString("Purveyor of the finest coffees"); org.setDescription(s); // Create primary contact, set name User primaryContact = blcm.createUser(); PersonName pName = blcm.createPersonName("Jane Doe"); primaryContact.setPersonName(pName); // Set primary contact phone number TelephoneNumber tNum = blcm.createTelephoneNumber(); tNum.setNumber("(800) 555-1212"); Collection phoneNums = new ArrayList(); phoneNums.add(tNum); primaryContact.setTelephoneNumbers(phoneNums); // Set primary contact email address EmailAddress emailAddress = blcm.createEmailAddress("[email protected]"); Collection emailAddresses = new ArrayList(); emailAddresses.add(emailAddress); primaryContact.setEmailAddresses(emailAddresses); // Set primary contact for organization org.setPrimaryContact(primaryContact);

Steps of Adding Classification:

Page 114: Chapter

1. Use BusinessQueryManager to find the taxonomy to which the organization wants to belong to. 2. Create a classification using the classification scheme and a concept (a taxonomy element) within the classification scheme. 3. Add the classification to the organization.

Example of Adding Classification to Organization:

// Set classification scheme to NAICS ClassificationScheme cScheme = bqm.findClassificationSchemeByName(null, "ntis-gov:naics"); // Create and add classification Classification classification = blcm.createClassification(cScheme, "Snack and Nonalcoholic Beverage Bars", "722213"); Collection classifications = new ArrayList(); classifications.add(classification); org.addClassifications(classifications);

JAXR Provider Must Provide Taxonomies of:

1. The North American Industry Classification System (NAICS)

http://www.census.gov/epcd/www/naics.html

2. Universal Standard Products and Services Classification (UNSPSC)

http://www.eccma.org/unspsc/

3. ISO 3166 country codes classification system maintained by the International Organization for Standardization (ISO)

http://www.iso.org/iso/en/prods-services/iso3166ma/index.html

Suppose the organization "Fly Away Airline Travel Agents" has a Web-based airline reservation service that its partner travel agencies must be able to use. The following code creates such a business and saves it to the registry. The business has contact information, a set of services it offers, and technical information for accessing those services:

public void saveOrganization() throws JAXRException { // Create Organization in memory Organization org = businessLifeCycleManager.createOrganization("Fly Away Airline Travel Agents"); // Create User -- maps to Contact for UDDI User user = businessLifeCycleManager.createUser(); PersonName personName = businessLifeCycleManager.createPersonName("Marie A Traveler"); TelephoneNumber telephoneNumber = businessLifeCycleManager.createTelephoneNumber(); telephoneNumber.setNumber("781-333-3333"); telephoneNumber.setType("office"); Collection numbers = new ArrayList(); numbers.add(telephoneNumber); EmailAddress email = businessLifeCycleManager.createEmailAddress("[email protected]", "office"); Collection emailAddresses = new ArrayList(); emailAddresses.add(email); user.setPersonName(personName); Collection telephoneNumbers = new ArrayList(); telephoneNumbers.add(telephoneNumber); user.setTelephoneNumbers(telephoneNumbers); user.setEmailAddresses(emailAddresses); org.setPrimaryContact(user); // Create service with service name and description Service service = businessLifeCycleManager.createService("Fly Away Airline Reservation Service"); service.setDescription(businessLifeCycleManager.createInternationalString("Flight Reservation Service")); // Create serviceBinding ServiceBinding serviceBinding = businessLifeCycleManager.createServiceBinding(); serviceBinding.setDescription(businessLifeCycleManager. createInternationalString("Information for airline reservation service access")); //Turn validation of URI off serviceBinding.setValidateURI(false); serviceBinding.setAccessURI("http://www.airlinetravel.com:8080/services.reservations.html ");

Page 115: Chapter

// Create the SpecificationLink information SpecificationLink specificationLink = businessLifeCycleManager.createSpecificationLink(); // Set usage description specificationLink.setUsageDescription(businessLifeCycleManager. createInternationalString("Search for Reservations when prompted")); String usageParameter = "Enter travel agent id when prompted"; Collection usageParameters = new ArrayList(); usageParameters.add(usageParameter); // Set usage parameters specificationLink.setUsageParameters(usageParameters); // Set specificationConcept on the specificationLink Concept httpSpecificationConcept = (Concept) businessLifeCycleManager.createObject(businessLifeCycleManager.CONCEPT); Key httpSpecificationKey = businessLifeCycleManager.createKey("uuid:68de9e80-ad09-469d-8a37-088422bfbc36"); httpSpecificationConcept.setKey(httpSpecificationKey); specificationLink.setSpecificationObject(httpSpecificationConcept); // Add the specificationLink to the serviceBinding serviceBinding.addSpecificationLink(specificationLink); // Add the serviceBinding to the service service.addServiceBinding(serviceBinding); // Add the service to the organization org.addService(service); // Add classifications to the organization ClassificationScheme naics = businessQueryManager.findClassificationSchemeByName(null, "ntis-gov:naics"); Classification classification = businessLifeCycleManager.createClassification(naics, "Air Transportation", "481"); org.addClassification(classification); Collection orgs = new ArrayList(); orgs.add(org); // Save organization and whole tree of related objects BulkResponse br = businessLifeCycleManager.saveOrganizations(orgs); if (br.getStatus() == JAXRResponse.STATUS_SUCCESS) { System.out.println("Successfully saved the organization to the registry provider."); } }

Given a scenario, implement Java EE based web service web-tier and/or EJB-tier basic security mechanisms, such as mutual authentication, SSL, and access control.

Prev Chapter 8. Security Next

Given a scenario, implement Java EE based web service web-tier and/or EJB-tier basic security mechanisms, such as mutual authentication, SSL, and access control.

• [NONE] blah

HTTP Basic Authentication

HTTP Basic Authentication requires that the server request a user name and password from the web client and verify that the user name and password are valid by comparing them against a database of authorized users. When basic authentication is declared, the following actions occur:

Page 116: Chapter

1. A client requests access to a protected resource. 2. The web server returns a dialog box that requests the user name and password. 3. The client submits the user name and password to the server. 4. The server authenticates the user in the specified realm and, if successful, returns the requested resource.

The following example shows how to specify basic authentication in your deployment descriptor:

<login-config> <auth-method>BASIC</auth-method> </login-config>

HTTP basic authentication is not a secure authentication mechanism. Basic authentication sends user names and passwords over the Internet as text that is Base64 encoded, and the target server is not authenticated. This form of authentication can expose user names and passwords. If someone can intercept the transmission, the user name and password information can easily be decoded. However, when a secure transport mechanism, such as SSL, or security at the network level, such as the IPSEC protocol or VPN strategies, is used in conjunction with basic authentication, some of these concerns can be alleviated.

Example application that uses HTTP basic authentication in a JAX-WS service

1. Annotate the Service

Annotations are used to specify which users are authorized to access which methods of the service. In this simple example,

the @RolesAllowedannotation is used to specify that users in the application role of basicUser are authorized

access to the sayHello(String name) method. This application role must be linked to a group of users on the Application Server.

The code snippet is as follows:

import javax.jws.WebMethod; import javax.jws.WebService; import javax.annotation.security.RolesAllowed; @WebService() public class Hello { private String message = new String("Hello, "); @WebMethod() @RolesAllowed("basicUser") public String sayHello(String name) { return message + name + "."; } }

2. Add Security Elements to the Deployment Descriptor

Page 117: Chapter

To enable basic authentication for the service, add security elements to the application deployment descriptor, web.xml. The

security elements that need to be added to the deployment descriptor include the security-constraint and login-config elements:

<web-app version="2.5" ...> <display-name>Basic Authentication Security Example</display-name> <servlet> <display-name>HelloService</display-name> <servlet-name>HelloService</servlet-name> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloService</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <security-constraint> <web-resource-collection> <web-resource-name>WRCollection</web-resource-name> <url-pattern>/hello</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>basicUser</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> </login-config> <security-role> <role-name>basicUser</role-name> </security-role> </web-app>

3. Set Security Properties In The Client Code

You can do the following:

HelloService service = new HelloService(); Hello proxy = service.getHelloPort(); BindingProvider bindingProvider = (BindingProvider)proxy; bindingProvider.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "userfoo"); bindingProvider.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "passbar");

BindingProvider.USERNAME_PROPERTY, BindingProvider.PASSWORD_PROPERTY are used primarily for service requests. When you instantiate Service, it fetches WSDL and the server is returning 401. You could try any one of the following solutions:

• Use java.net.Authenticator class in your client application.

• Provide a local access to the WSDL using catalog.

• Configure web.xml to allow GET requests without authentication.

Mutual Authentication

With mutual authentication, the server and the client authenticate one another. There are two types of mutual authentication:

Page 118: Chapter

• Certificate-based mutual authentication

• User name- and password-based mutual authentication

Certificate-Based Mutual Authentication

When using certificate-based mutual authentication, the following actions occur:

1. A client requests access to a protected resource. 2. The web server presents its certificate to the client. 3. The client verifies the server's certificate. 4. If successful, the client sends its certificate to the server. 5. The server verifies the client's credentials. 6. If successful, the server grants access to the protected resource requested by the client.

User Name- and Password-Based Mutual Authentication

In user name- and password-based mutual authentication, the following actions occur:

Page 119: Chapter

1. A client requests access to a protected resource. 2. The web server presents its certificate to the client. 3. The client verifies the server's certificate. 4. If successful, the client sends its user name and password to the server, which verifies the client's credentials. 5. If the verification is successful, the server grants access to the protected resource requested by the client.

Using JAX-WS-Based Web Services with SSL

1. Write the Class for the Web Service Endpoint

SSL has no impact on the Java code for the web service endpoint. The same code works for web services that use SSL or that don't use SSL.

In Java EE 5, you can use annotations to easily construct a JAX-WS web service. Here's an example of a web service implemented as an EJB endpoint:

import javax.annotation.Resource; import javax.ejb.Stateless; import javax.jws.WebService; import javax.xml.ws.WebServiceContext; @Stateless @WebService public class HelloEjb { @Resource WebServiceContext wsContext; public String hello(String msg) { return "Ejb WS: " + wsContext.getUserPrincipal() + ": " + msg; } }

The @Stateless annotation marks the class as a stateless session bean, and the @WebService annotation marks

the class as a web service. The@Resource annotation is used to declare resource dependencies that the class has - in essence, what resources the class needs. These resources are then injected into the endpoint implementation. In this example,

the annotation identifies a resource dependency on the WebServiceContext. The class needs

the WebServiceContext to get context information about requests, such as related security information.

Here's the same web service implemented as a servlet endpoint:

import javax.annotation.Resource; import javax.jws.WebService; import javax.xml.ws.WebServiceContext;

Page 120: Chapter

@WebService public class HelloServlet { @Resource WebServiceContext wsContext; public String hello(String msg) { return "Servlet WS: " + wsContext.getUserPrincipal() + ": " + msg; } }

2. Specify Security Information in Deployment Descriptors

To use SSL in a web service that is implemented as an EJB endpoint, you need to specify security information in a vendor-specific deployment descriptor. For a web service implemented as a servlet, you need to specify the security information in

the web.xml descriptor.

One important aspect of secure communication through SSL is server authentication, that is, confirming the identity of the server to the client. Another aspect is client authentication, where the server confirms the identity of the client. In SSL, you can have either server authentication or the combination of server and client authentication (but not client authentication alone). We use the term "mutual authentication" to mean the combination of server and client authentication. (Note however that other documents might attach a different meaning to mutual authentication. For example, in some documents, the term client authentication is synonymous with mutual authentication).

For SSL mutual authentication, you need to set the auth-method subelement of the login-config element

to CLIENT-CERT. You also need to set thetransport-guarantee element to CONFIDENTIAL.

Add the appropriate security elements to the web.xml deployment descriptor:

<?xml version="1.0"?> <web-app version="2.5" ...> <display-name>Secure Mutual Authentication Example</display-name> <security-constraint> <web-resource-collection> <web-resource-name>SecureHello</web-resource-name> <url-pattern>/hello</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>CLIENT-CERT</auth-method> </login-config> </web-app>

3. Write the Client

After deploying the web service, you can access it from a client program. The client program for a web service application that uses SSL is essentially the same as one that doesn't use SSL. The major difference is that instead of using HTTP as the internet

protocol, you need to use HTTPS. In the client, you use the @WebServiceRef annotation to declare a reference to a

web service. The value of the wsdlLocation parameter in @WebServiceRef is a URL that points to the location of the WSDL file for the service being referenced. So for a web service client that uses SSL,

the wsdlLocationparameter in the @WebServiceRef annotation needs to specify an HTTPS URL.

For example:

@WebServiceRef(wsdlLocation="https://server.com:8080/HelloEjbService/HelloEjb?WSDL") private static HelloEjbService helloEjbService;

You can then access the port for the web service and invoke the web service:

Page 121: Chapter

HelloEjb helloEjbPort = helloEjbService.getHelloEjbPort(); helloEjbPort.hello("Hello World");

Client-side artifacts are generated by accessing the WSDL file through HTTPS. To do that, you need to specify the location of a truststore file for the server and its password in the environment variable. In SSL, you can use certificates to authenticate the server or for mutual authentication of both the server and client. The truststore file for the server contains the trusted certificates for the server and its keys.

4. Set Up the Client Truststore and Keystore

In addition to a truststore file for the server, you also need a truststore file for the client. The client validates the server certificate against a set of certificates in its truststore. For a secure connection to be made using SSL, the client-side truststore needs to trust the server certificate. For SSL mutual authentication, the server-side truststore also needs to trust the client certificate. If you modify the server-side truststore, you need to restart the server (this allows use of the new certificate). You might not need to do this in a production environment because production certificates are signed by a common Certificate Authority (CA).

For SSL mutual authentication, you need to provide your own key in a client keystore (a file that contains the client's keys and

certificates). You can use keytool, a key and certificate management utility in JDK 5.0, to generate the keystore.

The certificate has to be loaded to the client, to achieve this, keytool command is used

keytool -import -trustcacerts -alias FOO -file "FOO_PATH\foo.cer" -storetype JKS -keystore "FOO_PATH\foo.keystore"

5. Run the Client

Before you run the client that access a web service with SSL, you need to set the value of the environment variable.

For SSL mutual authentication, set the value to:

System.setProperty("javax.net.ssl.keyStore", "FOO_PATH/foo.keystore"); System.setProperty("javax.net.ssl.keyStorePassword", "changeit"); System.setProperty("javax.net.ssl.keyStoreType", "JKS"); System.setProperty("javax.net.ssl.trustStore", "FOO_PATH/foo.keystore"); System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol"); Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

Describe WS-Policy that defines a base set of constructs that can be used and extended by other Web services specifications to describe a broad range of service requirements and capabilities.

Advanced web service features are enabled and configured using a mechanism defined by the Web Services Policy Framework (WS-Policy) specification. A web service expresses its requirements and capabilities via policies embedded in the service's WSDL description. A service consumer verifies it can handle the expressed requirements and, optionally, uses server capabilities advertised in policies.

Technologies like Reliable Messaging, Addressing, or Secure Conversations, provides a set of policy assertions it can process. Those assertions provide the necessary configuration details to the Metro run-time to enable proper operation of these features used by a given web service. The assertions may specify particular configuration settings or rely on default settings that are pre-determined by the specific technology. For instance, in the snippet shown

below,wsrm:AcknowledgementInterval and wsrm:InactivityTimeout are both optional and could be omitted. The following is an XML snippet showing WS-Policy assertions for WS-Addressing and WS-Reliable Messaging:

<wsp:Policy wsu:Id="AddNumbers_policy"> <wsp:ExactlyOne> <wsp:All> <wsaw:UsingAddressing/> <wsrm:RMAssertion> <wsrm:InactivityTimeout Milliseconds="600000"/> <wsrm:AcknowledgementInterval Milliseconds="200"/> </wsrm:RMAssertion> </wsp:All>

Page 122: Chapter

</wsp:ExactlyOne> </wsp:Policy>

This snippet would be equally valid in either a WSIT configuration file or a web service's WSDL document.

Given an XML schema for a document style Web service create a WSDL file that describes the service and generate a service implementation.

Empty

Method

The wsdl:operation element corresponding to each method has one or more child elements as follows:

• A wsdl:input element that refers to an associated wsdl:message element to describe the operation input.

• (Two-way methods only) an optional wsdl:output element that refers to

a wsdl:message to describe the operation output.

• (Two-way methods only) zero or more wsdl:fault child elements, one for each exception thrown by

the method. The wsdl:fault child elements refer to associated wsdl:message elements to describe each fault.

Each wsdl:message element has one of the following:

• Document style

A single wsdl:part child element that refers, via an element attribute, to a global element

declaration in the wsdl:types section:

@WebService public interface StockQuoteProvider { float getPrice(String tickerSymbol) throws TickerException; } <types> <xsd:schema targetNamespace="..."> <!-- element declarations --> <xsd:element name="getPrice" type="tns:getPriceType"/> <xsd:element name="getPriceResponse" type="tns:getPriceResponseType"/> <xsd:element name="TickerException" type="tns:TickerExceptionType"/> <!-- type definitions --> ... </xsd:schema> </types> <message name="getPrice"> <part name="getPrice" element="tns:getPrice"/> </message> <message name="getPriceResponse"> <part name="getPriceResponse" element="tns:getPriceResponse"/> </message> <message name="TickerException"> <part name="TickerException" element="tns:TickerException"/> </message> <portType name="StockQuoteProvider"> <operation name="getPrice"> <input message="tns:getPrice"/>

Page 123: Chapter

<output message="tns:getPriceResponse"/> <fault message="tns:TickerException"/> </operation> </portType>

• RPC style

Zero or more wsdl:part child elements (one per method parameter and one for a non-void return

value) that refer, via a type attribute, to named type declarations in the wsdl:types section:

@WebService public interface StockQuoteProvider { float getPrice(String tickerSymbol) throws TickerException; } <types> <xsd:schema targetNamespace="..."> <!-- element declarations --> <xsd:element name="TickerException" type="tns:TickerExceptionType"/> <!-- type definitions --> ... </xsd:schema> </types> <message name="getPrice"> <part name="tickerSymbol" type="xsd:string"/> </message> <message name="getPriceResponse"> <part name="return" type="xsd:float"/> </message> <message name="TickerException"> <part name="TickerException" element="tns:TickerException"/> </message> <portType name="StockQuoteProvider"> <operation name="getPrice"> <input message="tns:getPrice"/> <output message="tns:getPriceResponse"/> <fault message="tns:TickerException"/> </operation> </portType>

Each method in a Java SEI is mapped to a soap:operation child element of the

corresponding wsdl:operation. The value of the style attribute of

thesoap:operation is document or rpc.

If not specified, the value defaults to the value of the style attribute of the soap:binding. WS-I Basic Profile requires that all operations within a given SOAP HTTP binding instance have the same binding style.

The parameters of a Java method are mapped to soap:body or soap:header child elements of

the wsdl:input and wsdl:output elements for eachwsdl:operation binding element. The

value of the use attribute of the soap:body is literal.

Example shows using document style:

<types> <schema targetNamespace="..."> <xsd:element name="getPrice" type="tns:getPriceType"/> <xsd:complexType name="getPriceType"> <xsd:sequence> <xsd:element name="tickerSymbol" type="xsd:string"/>

Page 124: Chapter

</xsd:sequence> </xsd:complexType> <xsd:element name="getPriceResponse" type="tns:getPriceResponseType"/> <xsd:complexType name="getPriceResponseType"> <xsd:sequence> <xsd:element name="return" type="xsd:float"/> </xsd:sequence> </xsd:complexType> </schema> </types> <message name="getPrice"> <part name="getPrice" element="tns:getPrice"/> </message> <message name="getPriceResponse"> <part name="getPriceResponse" element="tns:getPriceResponse"/> </message> <portType name="StockQuoteProvider"> <operation name="getPrice" parameterOrder="tickerSymbol"> <input message="tns:getPrice"/> <output message="tns:getPriceResponse"/> </operation> </portType> <binding name="StockQuoteProviderBinding"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <operation name="getPrice" parameterOrder="tickerSymbol"> <soap:operation/> <input message="tns:getPrice"> <soap:body use="literal"/> </input> <output message="tns:getPriceResponse"> <soap:body use="literal"/> </output> </operation> </binding>

Example shows using rpc style:

<types> <schema targetNamespace="..."> <xsd:element name="getPrice" type="tns:getPriceType"/> <xsd:complexType name="getPriceType"> <xsd:sequence> <xsd:element form="unqualified" name="tickerSymbol" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:element name="getPriceResponse" type="tns:getPriceResponseType"/> <xsd:complexType name="getPriceResponseType"> <xsd:sequence> <xsd:element form="unqualified" name="return" type="xsd:float"/> </xsd:sequence> </xsd:complexType> </schema> </types> <message name="getPrice"> <part name="tickerSymbol" type="xsd:string"/> </message> <message name="getPriceResponse"> <part name="result" type="xsd:float"/> </message> <portType name="StockQuoteProvider"> <operation name="getPrice"> <input message="tns:getPrice"/> <output message="tns:getPriceResponse"/> </operation> </portType> <binding name="StockQuoteProviderBinding"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>

Page 125: Chapter

<operation name="getPrice"> <soap:operation/> <input message="tns:getPrice"> <soap:body use="literal"/> </input> <output message="tns:getPriceResponse"> <soap:body use="literal"/> </output> </operation> </binding>

Implement a SOAP logging mechanism for testing and debugging a Web service application using Java EE Web Service APIs.

• [NONE] blah

Handlers are message interceptors that can be easily plugged in to the JAX-WS runtime to do additional processing of the inbound and outbound messages. JAX-WS defines two types of handlers, logical handlers and protocol handlers. Protocol handlers are specific to a protocol and may access or change the protocol specific aspects of a message. Logical handlers are protocol-agnostic and cannot change any protocol-specific parts (like headers) of a message. Logical handlers act only on the payload of the message.

SOAP handlers are generally used to process SOAP-specific information, such as SOAP headers. For example, a SOAP Handler can process security headers in a message and pass the request to the endpoint if the message has the required credentials. Logical handlers are commonly used if the processing does not need access to SOAP headers, for validation of the payload, and with Representational State Transfer ("REST") style web services. In addition, logical handlers can

use Java API for XML Binding (JAXB) for processing the payload. If you have the JAXBContext object, it's simple to alter something in a message with a logical handler. You can get the JAXB objects and call Java methods on them

rather than dealing with Source objects or SOAPMessage objects using the SOAP with Attachments API for Java (SAAJ) in a SOAP handler.

Handlers are invoked with a message context, which provides methods that the handler uses to access and modify inbound or outbound messages. The message context also has properties that the handler can process. These properties can be used to communicate additional information or metadata that is not specified in the message. The additional information can be exchanged between a handler and service implementation or between a handler and a web service client.

SOAP handlers extend javax.xml.ws.handler.soap.SOAPHandler. The JAX-WS

specification defines the SOAPHandler class for SOAP binding. When a SOAP handler is invoked,

a SOAPMessageContext object is specified in the request. The SOAPMessageContext object

provides methods to access a SOAPMessage (the class for SOAP messages). Specifically, the

method getMessage() in SOAPMesageContext retrieves the SOAPMessage. After getting

a SOAPMessage, you can use SAAJ to manipulate it.

Logical handlers extend javax.xml.ws.handler.LogicalHandler. They provide access to the message context and the message payload. If you use SOAP over HTTP for the message exchange, the content of the SOAP body forms the payload. If you use XML over HTTP, the XML content of the primary part of the message forms

the payload. When a logical handler is invoked, a LogicalMessageContext object is specified in the

request. The method getMessage() inLogicalMessageContext returns

a LogicalMessage. The LogicalMessage represents a protocol-neutral XML message and contains methods that provide access to the payload of the message.

The following figure illustrates the relationship between the message contexts, the objects they can be used to retrieve, and the parts of a message those objects cover:

Page 126: Chapter

Logical handlers can coexist with SOAP handlers in a handler chain. During runtime, the handler chain is reordered so that for an outbound message thelogical handlers execute BEFORE the SOAP handlers. For an inbound message, the SOAP handlers execute BEFORE the logical handlers.

Writing a SOAP Message Handler

Let's look at a simple SOAP handler. SOAPLoggingHandler is a SOAP handler that logs calls to a web

service. Here's a code snippet from SOAPLoggingHandler:

public class SOAPLoggingHandler implements SOAPHandler<SOAPMessageContext> { ... public boolean handleMessage(SOAPMessageContext smc) { logToSystemOut(smc); return true; } public boolean handleFault(SOAPMessageContext smc) { logToSystemOut(smc); return true; } public void close(MessageContext messageContext) { } ... }

Like all SOAP handlers, SOAPLoggingHandler implements the SOAPHandler interface. Notice

that SOAPLoggingHandler also implements three

Page 127: Chapter

methods:handleMessage(), handleFault(), and close().

The SOAPHandler interface is a subinterface of the Handler interface.

The handleMessage(), handleFault(), and close() methods are the three methods defined

in the Handler interface, and should be implemented in all basic handlers. Here's how the methods are used:

• handleMessage() is called for normal processing of inbound and outbound messages.

• handleFault() is called when a message contains a protocol fault.

• close() is called after the completion of message processing by all handlers for each web service invocation, that is, after the completion of a SOAP method exchange pattern (or "MEP").

The logging is done in the handler's logToSystemOut() method that both

the handleMessage() and handleFault() methods call:

private void logToSystemOut(SOAPMessageContext smc) { Boolean outboundProperty = (Boolean)smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); if (outboundProperty.booleanValue()) { out.println("\nOutbound message:"); } else { out.println("\nInbound message:"); } SOAPMessage message = smc.getMessage(); try { message.writeTo(out); out.println(""); } catch (Exception e) { out.println("Exception in handler: " + e); } }

Notice that the logToSystemOut() method accesses

a SOAPMessageContext property, MESSAGE_OUTBOUND_PROPERTY, and uses

a SOAPMessageContext method,getMessage(). The value

of MESSAGE_OUTBOUND_PROPERTY indicates the message direction. A value of true means that the

message is outbound. A value offalse indicates an inbound message. Based on the property

value, logToSystemOut() prints either "Outbound message" or "Inbound message". It then usesgetMessage() to get the SOAP message, and prints it.

Writing a Logical Message Handler

The LogicalLoggingHandler file is a logical message handler. Like

the SOAPLoggingHandler, it logs calls to a web service. Here's a code snippet

fromLogicalLoggingHandler:

public class LogicalLoggingHandler implements LogicalHandler<LogicalMessageContext> { ... public boolean handleMessage(LogicalMessageContext context) { return processMessage(context); } public boolean handleFault(LogicalMessageContext context) { return processMessage(context); } public void close(MessageContext context) { // Clean up Resources } }

Like all logical handlers, LogicalLoggingHandler implements the LogicalHandler interface.

Page 128: Chapter

And like all handlers it implements the handleMessage(),handleFault(),

and close() methods.

The logging is done in the handler's processMessage() method that both

the handleMessage() and handleFault() methods call:

private boolean processMessage(LogicalMessageContext context) { Boolean outboundProperty = (Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); if (outboundProperty) { out.println("\nOutbound message:"); } else { out.println("\nInbound message:"); } LogicalMessage lm = context.getMessage(); Source payload = lm.getPayload(); // Process Payload Source printSource(payload); // .... // If the payload is modified, // do lm.setPayload(source) to be safe. Without it, // behavior may vary on the kind of source returned in // lm.getPayload(). // See LogicalMessage JavaDoc for more details. // lm.setPayload(modifiedPayload); return true; }

The processMessage() method accesses and manipulates the message payload using the logical message

context for the logical handler. It calls theLogicalMessage method, getPayload(), to get the

payload of the message. The payload is returned as a Source object.

Notice the commented out portion of processMessage(). In some cases, you might need to call

the LogicalMessage method, setPayload(), after a modification is made to the payload. The

source returned by getPayload() depends on the JAX-WS runtime. If the returned source

is DOMSource, a modification to the encapsulated DOM tree changes the message payload in place. In that case,

there is no need to subsequently call setPayload(). However, other types of returned source provide only read

access to the message. In those cases, you need to call setPayload() after any modifications.

You can also pass a JAXBContext object in the call to getPayload(), to get the payload as a JAXB object. Here's an example:

LogicalMessage lm = context.getMessage(); Object jaxbObject = lm.getPayload(jaxbContext); // Modify JAXB Object lm.setPayload(modifiedJaxbObject,jaxbContext);

Note that there is no connection between the returned object and the message payload - to change the payload, you

need to call setPayload().

Advanced web service features are enabled and configured using a mechanism defined by the Web Services Policy Framework (WS-Policy) specification. A web service expresses its requirements and capabilities via policies embedded in the service's WSDL description. A service consumer verifies it can handle the expressed requirements and, optionally, uses server capabilities advertised in policies.

Technologies like Reliable Messaging, Addressing, or Secure Conversations, provides a set of policy assertions it can process. Those assertions provide the necessary configuration details to the Metro run-time to enable proper operation of these features used by a given web service. The assertions may specify particular configuration settings or rely on default settings that are pre-determined by the specific technology. For instance, in the snippet shown

below,wsrm:AcknowledgementInterval and wsrm:InactivityTimeout are both optional and could be omitted. The following is an XML snippet showing WS-Policy assertions for WS-Addressing and WS-Reliable Messaging:

Page 129: Chapter

Given a set of requirements, create code to handle system and service exceptions and faults received by a Web services client.

• [NONE] blah

WSDL-to-Java mapping

Let's look at the WSDL-to-Java mapping of faults to exceptions, starting with the WSDL. Run your favorite JAX-WS WSDL-to-Java code generator on this WSDL. It gives you the generated interface and fault classes.

<wsdl:definitions targetNamespace="urn:fault.sample" xmlns:tns="urn:fault.sample" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> <wsdl:types> <xsd:schema targetNamespace="urn:fault.sample" xmlns:tns="urn:fault.sample" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="op" type="tns:Op"/> <xsd:complexType name="Op"> <xsd:sequence> <xsd:element name="in" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:element name="opResponse" type="tns:OpResponse"/> <xsd:complexType name="OpResponse"> <xsd:sequence> <xsd:element name="out" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:element name="faultElement" type="tns:Fault"/> <xsd:complexType name="Fault"> <xsd:sequence> <xsd:element name="code" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:schema> </wsdl:types> <wsdl:message name="opRequest"> <wsdl:part name="parameters" element="tns:op"/> </wsdl:message> <wsdl:message name="opResponse"> <wsdl:part name="parameters" element="tns:opResponse"/> </wsdl:message> <wsdl:message name="faultMsg"> <wsdl:part name="parameters" element="tns:faultElement"/> </wsdl:message> <wsdl:portType name="PT"> <wsdl:operation name="op"> <wsdl:input message="tns:opRequest"/> <wsdl:output message="tns:opResponse"/> <wsdl:fault name="fault" message="tns:faultMsg"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="Binding" type="tns:PT"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="op"> <soap:operation soapAction=""/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> <wsdl:fault name="fault"> <soap:fault use="literal" name="fault"/> </wsdl:fault> </wsdl:operation> </wsdl:binding> <wsdl:service name="Service">

Page 130: Chapter

<wsdl:port name="Port" binding="tns:Binding"> <soap:address location="http://www.example.org/"/> </wsdl:port> </wsdl:service> </wsdl:definitions>

Generated Java interface:

package sample.fault; public interface PT { public String op(String in) throws FaultMsg; }

The Java exception name is derived from the WSDL fault message's name; in this case FaultMsg:

package sample.fault; public class FaultMsg extends Exception { private Fault faultInfo; public FaultMsg(String message, Fault faultInfo) {...} public FaultMsg(String message, Fault faultInfo, Throwable cause) {...} public Fault getFaultInfo() {...} }

All mapped JAX-WS exceptions contain a private faultInfo instance variable. The type of this faultInfo is derived from the

schema, which the fault's wrapper element refers to; in this case it's Fault:

package sample.fault; public class Fault { protected String code; public String getCode() {...} public void setCode(String value) {...} }

Why does a JAX-WS mapping of faults create a fault class and a fault info class? The reason is that JAX-WS delegates the generation of schema mappings to Java Architecture for XML Binding (JAXB). JAX-WS knows how to do Web services stuff, but it doesn't know how to do schema stuff. JAXB knows schema. A fault or exception is a Web services artifact. The data in a fault is a schema artifact. So the JAX-WS generator generates the exception, and the JAXB generator generates the Java bean containing the exception's data.

Java-to-WSDL mapping

JAX-WS seems to prefer that you build exceptions like the ones it generates, with the exception itself separate from the Java bean data for the exception. If you follow this pattern, you get the reverse of the mapping described in the previous section.

But separating the exception data from the exception is not typical of how a Java programmer writes exceptions. So JAX-WS also provides a mapping for the more natural exception. A simple example of this natural pattern is shown below.

SEI:

package sample2.fault; public interface PT { public String op(String in) throws Fault; }

Exception: package sample2.fault; public class Fault extends Exception { public Fault(String code) {...} public String getCode() {...} public void setCode(String value) {...} } ™

WSDL generated from above Java:

Page 131: Chapter

<definitions targetNamespace="http://fault.sample2/" xmlns:tns="http://fault.sample2/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> <types> <xsd:schema> <xsd:import namespace="http://fault.sample2/" schemaLocation="PTImplService_schema1.xsd"/> </xsd:schema> </types> <message name="op"> <part element="tns:op" name="parameters"/> </message> <message name="opResponse"> <part element="tns:opResponse" name="parameters"/> </message> <message name="Fault"> <part element="tns:Fault" name="fault"/> </message> <portType name="PTImpl"> <operation name="op"> <input message="tns:op"/> <output message="tns:opResponse"/> <fault message="tns:Fault" name="Fault"/> </operation> </portType> <binding name="PTImplPortBinding" type="tns:PTImpl"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="op"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> <fault name="Fault"> <soap:fault name="Fault" use="literal"/> </fault> </operation> </binding> <service name="PTImplService"> <port binding="tns:PTImplPortBinding" name="PTImplPort"> <soap:address location="https://localhost:9444/SampleFault/PTImplService"/> </port> </service> </definitions>

Schema generated from above Java:

<xs:schema targetNamespace="http://fault.sample2/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://fault.sample2/"> <xs:element name="Fault" type="tns:Fault"/> <xs:element name="op" type="tns:op"/> <xs:element name="opResponse" type="tns:opResponse"/> <xs:complexType name="op"> <xs:sequence> <xs:element minOccurs="0" name="arg0" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="opResponse"> <xs:sequence> <xs:element minOccurs="0" name="return" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="Fault"> <xs:sequence>

Page 132: Chapter

<xs:element minOccurs="0" name="code" type="xs:string"/> <xs:element minOccurs="0" name="message" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:schema>

Unmodeled faults

What happens when an unmodeled fault occurs? For example, what happens when the service above throws an exception other

than sample2.fault.Fault(for instance, NullPointerException)? What happens on the client? The answer to that depends on the messaging protocol. For instance, when communicating via SOAP/HTTP, the server-side SOAP engine creates a SOAP

message containing a SOAP fault with information relevant to the problem in the faultcode and faultstring fields:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <soapenv:Fault> <faultcode>soapenv:Server</faultcode> <faultstring>java.lang.NullPointerException</faultstring> <detail/> </soapenv:Fault> </soapenv:Body> </soapenv:Envelope>

Because a SOAP fault is returned to the client, JAX-WS has defined an exception named SOAPFaultException. When the

service throws an unmodeled fault, the client receives a SOAPFaultException.

javax.xml.ws.soap.SOAPFaultException is a protocol-specific exception. It

extends javax.xml.ws.ProtocolException. JAX-WS defines another extension

ofProtocolException: javax.xml.ws.http.HTTPException for the XML/HTTP communication channel. Those are the only standardized bindings defined for WSDL. For other bindings, assume the binding provider defines other extensions

of ProtocolException, one for each new binding.

JAX-WS defines a number of Java classes, such as Service, BindingProvider, and Dispatch. If calls to those classes

fail, they throw WebServiceException, the general-purpose exception for the JAX-WS APIs.

java.lang.Object extended by java.lang.Throwable extended by java.lang.Exception extended by java.lang.RuntimeException extended by javax.xml.ws.WebServiceException extended by javax.xml.ws.ProtocolException extended by javax.xml.ws.soap.SOAPFaultException extended by javax.xml.ws.http.HTTPException

Chapter 10. Web Services Interoperability Technologies

Describe WSIT, the features of each WSIT technology and the standards that WSIT Implements for each technology and how it works.

Sun is working closely with Microsoft to ensure interoperability of web services enterprise technologies such as message optimization, reliable messaging, and security. The initial release of WSIT is a product of this joint effort. WSIT is an implementation of a number of open web services specifications to support enterprise features. In addition to message optimization, reliable messaging, and security, WSIT includes a bootstrapping and configuration technology. Figure below shows the underlying services that were implemented for each technology.

Page 133: Chapter

Starting with the core XML support currently built into the Java platform, WSIT uses or extends existing features and adds new support for interoperable web services. See the following sections for an overview of each feature:

• Bootstrapping and Configuration

Bootstrapping and configuration consists of using a URL to access a web service, retrieving its WSDL file, and using the WSDL file to create a web service client that can access and consume a web service. The process consists of the following steps, which are shown below:

1. Client acquires the URL for a web service that it wants to access and consume. How you acquire the URL is outside the scope of this tutorial. For example, you might look up the URL in a Web Services registry.

2. The client uses the URL and the wsimport tool to send a MetadataExchangeRequest to access the web service and retrieve the WSDL file. The WSDL file contains a description of the web service endpoint, including WS-Policy assertions that describe the security and/or reliability capabilities and requirements of the service. The description describes the requirements that must be satisfied to access and consume the web service.

3. The client uses the WSDL file to create the web service client.

Page 134: Chapter

4. The web service client accesses and consumes the web service.

• Message Optimization Technology

A primary function of web services applications is to share data among applications over the Internet. The data shared can vary in format and include large binary payloads, such as documents, images, music files, and so on. When large binary objects are encoded into XML format for inclusion in SOAP messages, even larger files are produced. When a web service processes and transmits these large files over the network, the performance of the web service application and the network are negatively affected. In the worst case scenario the effects are as follows:

o The performance of the web service application degrades to a point that it is no longer useful.

o The network gets bogged down with more traffic than the allotted bandwidth can handle.

One way to deal with this problem is to encode the binary objects so as to optimize both the SOAP application processing time and the bandwidth required to transmit the SOAP message over the network. In short, XML needs to be optimized for web services. This is the exactly what the Message Optimization technology does. It ensures that web services messages are transmitted over the Internet in the most efficient manner.

Sun recommends that you use message optimization if your web service client or web service endpoint will be required to process binary encoded XML documents larger than 1KB.

• Reliable Messaging Technology

Reliable Messaging is a Quality of Service (QoS) technology for building more reliable web services. Reliability is measured by a system's ability to deliver messages from point A to point B without error. The primary purpose of Reliable Messaging is to ensure the delivery of application messages to web service endpoints.

The reliable messaging technology ensures that messages in a given message sequence are delivered at least once and not more than once and optionally in the correct order. When messages in a given sequence are lost in transit or delivered out of order, this technology enables systems to recover from such failures. If a message is lost in transit, the sending system retransmits the message until its receipt is acknowledged by the receiving system. If messages are received out of order, the receiving system may re-order the messages into the correct order.

The Reliable Messaging technology can also be used to implement session management. A unique message sequence is created for each client-side proxy and the lifetime of the sequence identifier coincides with the lifetime of the proxy. Therefore, each message sequence can be viewed as a session and can be used to implement session management.

You should consider using reliable messaging if the web service is experiencing the following types of problems:

o Communication failures are occurring that result in the network being unavailable or connections being. dropped

o Application messages are being lost in transit.

o Application messages are arriving at their destination out of order and ordered delivery is a requirement.

To help decide whether or not to use reliable messaging, weigh the following advantages and disadvantages:

o Enabling reliable messaging ensures that messages are delivered exactly once from the source to the destination and, if the ordered-delivery option is enabled, ensures that messages are delivered in order.

o Enabling reliable messaging causes a degradation of web service performance, especially if the ordered delivery option is enabled.

o Non-reliable messaging clients cannot interoperate with web services that have reliable messaging enabled.

• Security Technology

Until now, web services have relied on transport-based security such as SSL to provide point-to-point security. WSIT implements WS-Security so as to provide interoperable message content integrity and confidentiality, even when messages pass through intermediary nodes before reaching their destination endpoint. WS-Security as provided by WSIT is in addition to existing transport-level security, which may still be used.

WSIT also enhances security by implementing WS-Secure Conversation, which enables a consumer and provider to establish a shared security context when a multiple-message-exchange sequence is first initiated. Subsequent messages use derived session keys that increase the overall security while reducing the security processing overhead for each message.

Further, WSIT implements two additional features to improve security in web services:

o Web Services Security Policy -- Enables web services to use security assertions to clearly represent security preferences and requirements for web service endpoints.

o Web Services Trust -- Enables web service applications to use SOAP messages to request security tokens that can then be used to establish trusted communications between a client and a web service.

Page 135: Chapter

WSIT implements these features in such a way as to ensure that web service binding security requirements, as defined in the WSDL file, can interoperate with and be consumed by WSIT and WCF endpoints.

Describe how to create a WSIT client from a Web Service Description Language (WSDL) file.

Describe how to configure web service providers and clients to use message optimization.

MTOM (Message Transmission and Optimization Mechanism) together with XOP (XML Binary Optimized Packaging) defines how an XML binary data such

asxs:base64Binary or xs:hexBinary can be optimally transmitted over the wire.

XML type, such as xs:base64Binary is sent in lined inside the SOAP envelope. This gets quite in-efficient when the data size is more, for example a SOAP endpoint that exchanges images/songs etc. MTOM specifies how XOP packaging can be used to send the binary data optimally.

MTOM feature is disabled in JAX-WS by default. It can be enabled on the client and server. Once enabled all the XML binary data, XML elements of

typexs:base64Binary and xs:hexBinary is optimally transmitted.

An schema element of type xs:bas64Binary or xs:hexBinary can be annotated by using attribute reference using xmime:expectedContentType2.0 specification defines xmime:expectedContentType to Java type mapping:

image/gif java.awt.Image image/jpg java.awt.Image text/plain java.lang.String text/xml javax.xml.transform.Source application/xml javax.xml.transform.Source multipart/* javax.activation.DataHandler all other types javax.activation.DataHandler <element name="image" type="base64Binary" />

is mapped to:

byte[] <element name="image" type="base64Binary" xmime:expectedContentTypes="image/jpeg" xmlns:xmime="http://www.w3.org/2005/05/xmlmime"/>

is mapped to:

java.awt.Image

How to enable MTOM in JAX-WS 2.0

• Enabling MTOM on Server

o Enable using @javax.xml.ws.soap.MTOM annotation on the endpoint (SEI) implementation class:

o @javax.xml.ws.soap.MTOM

o @WebService (endpointInterface = "mtom.server.Hello")

o public class HelloImpl implements Hello {

o ....

o }

o MTOM can be also be enabled on an endpoint by specifying enable-mtom attribute to true on an endpoint element in sun-jaxws.xmldescriptor:

o

o <?xml version="1.0" encoding="UTF-8"?>

o <endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime' version='2.0'>

o <endpoint name="Mtom" implementation="mtom.server.HelloImpl"

o url-pattern="/hello"

o enable-mtom="true"/>

Page 136: Chapter

o </endpoints>

o

o Enable using @BindingType on the endpoint (SEI) implementation class:

@BindingType(value=javax.xml.ws.SOAPBinding.SOAP11HTTP_MTOM_BINDING) will enable MTOM on the deployed endpoint for SOAP 1.1 binding.

@BindingType(value=javax.xml.ws.SOAPBinding.SOAP12HTTP_MTOM_BINDING) will enable MTOM on the deployed endpoint for SOAP 1.2 binding.

• Enabling MTOM on Client

o To enable MTOM on client-side, pass javax.xml.ws.soap.MTOMFeature as WebServiceFeature parameter while crating

the Proxy or Dispatch. Here is the code snippet from the client MtomApp.java of the MTOM sample:

Hello port = new HelloService().getHelloPort(new MTOMFeature()); - gives a proxy with MTOM enabled.

javax.xml.ws.Service.createDispatch( .... ,new MTOMFeature()); - gives a Dispatchenabled.

o JAX-WS 2.0 specification has defined API to enable and to check if the MTOM is enabled.

javax.xml.ws.soap.SOAPBinding.setMTOMEnabled(boolean enable) - enable or disable MTOM.

javax.xml.ws.soap.SOAPBinding.isMTOMEnabled() - returns true if MTOM is enabled otherwise false.

Hello port = new HelloService.getHelloPort(); //get the binding and enable mtom SOAPBinding binding = (SOAPBinding)((BindingProvider)port).getBinding(); boolean mtomEnabled = binding.isMTOMEnabled(); binding.setMTOMEnabled(true);

As defined by JAXB 2.0 specification xs:base64Binary and xs:hexBinary mapping to java is byte[]. JAXWS implementation has set a threshold of 1KB

ofbyte[] size. This threshold can be modified using implementation specific

property com.sun.xml.ws.developer.JAXWSProperties.MTOM_THRESHOLD_VALUE in the RequestContext on the client side and in

the MessageContext on the server side.

If the byte[] that is being sent is less than this threshold (default is 1KB) then the binary data is base64 encoded by JAXB and in lined inside the SOAP Bodyotherwise the binary

data is sent as attachment mime part in Multipart/Related package and XML infoset for the binary data is XOP encoded by JAXB -<xop:Include href=...>used to reference the attachment. The XOP encoding and packaging is done as per described by the XOP packaging rules. Thehref is the the Content-ID of the attachment and is

encoded as per CID URI scheme defined in RFC 2111. xmime:contentType attribute may appear on the element that includes binary data to indicate preferred media type as annotated on the corresponding schema.

What is MTOM

Perhaps the best way to understand the pros and cons of MTOM is to see an actual on-the-wire message. See an example below:

Content-Type: Multipart/Related; start-info="text/xml"; type="application/xop+xml"; boundary="----=_Part_0_1744155.1118953559416" Content-Length: 3453 SOAPAction: "" ------=_Part_1_4558657.1118953559446 Content-Type: application/xop+xml; type="text/xml"; charset=utf-8 <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">

Page 137: Chapter

<S:Body> <Detail xmlns="http://example.org/mtom/data"> <image> <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:[email protected]" /> </image> </Detail> </S:Body> </S:Envelope> ------=_Part_1_4558657.1118953559446 Content-Type: image/jpeg Content-ID: <[email protected]> ... binary data ...

The noteworthy points are:

1. The binary attachment is packaged in a MIME multi-part message (the same mechanism used in e-mail to handle attachments).

2. An xop:Include element is used to mark where the binary data is. 3. The actual binary data is kept in a different MIME part.

MTOM is efficient, in the sense that it doesn't have the 33% size increase penalty that xs:base64Binary has. It is interoperable, in the sense that it is a W3C standard. However, MIME multipart incurs a small cost proportional to the number of attachments, so it is not suitable for a large number of tiny attachments.

Schema:

<element name="Detail" type="types:DetailType"/> <complexType name="DetailType"> <sequence> <element name="image" type="base64Binary" /> </sequence> </complexType>

JAX-WS and MTOM example

JAX-WS MTOM WSDL:

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://attachment.tip/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://attachment.tip/"> <types/> <message name="sendImage"> <part name="image" type="xsd:base64Binary"/> </message> <message name="sendImageResponse"/> <message name="sendOctet"> <part name="octet" type="xsd:base64Binary"/> </message> <message name="sendOctetResponse"/> <portType name="AttachmentTip"> <operation name="sendImage"> <input message="tns:sendImage"/> <output message="tns:sendImageResponse"/> </operation> <operation name="sendOctet"> <input message="tns:sendOctet"/> <output message="tns:sendOctetResponse"/> </operation> </portType> <binding name="AttachmentBinding" type="tns:AttachmentTip"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="sendImage"> <soap:operation soapAction=""/> <input> <soap:body namespace="http://attachment.tip/" use="literal"/> </input>

Page 138: Chapter

<output> <soap:body namespace="http://attachment.tip/" use="literal"/> </output> </operation> <operation name="sendOctet"> <soap:operation soapAction=""/> <input> <soap:body namespace="http://attachment.tip/" use="literal"/> </input> <output> <soap:body namespace="http://attachment.tip/" use="literal"/> </output> </operation> </binding> <service name="AttachmentService"> <port binding="tns:AttachmentBinding" name="AttachmentTip"> <soap:address location="http://localhost:9080/MTOMService/services/AttachmentTip"/> </port> </service> </definitions>

The MTOM binding contains no MIME information. In fact, there's no way to tell, from the WSDL, that you're dealing with attachments; the WSDL's binding looks like a normal binding.

JAX-WS MTOM Java interface:

package tip.attachment; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; @WebService(name = "AttachmentTip", targetNamespace = "http://attachment.tip/") @SOAPBinding(style = SOAPBinding.Style.RPC) public interface AttachmentTip { @WebMethod public void sendImage( @WebParam(name = "image", partName = "image") byte[] image ); @WebMethod public void sendOctet( @WebParam(name = "octet", partName = "octet") byte[] octet ); }

Because the WSDL is a normal-looking WSDL with no hint of attachments, you end up with a Java interface that reflects that as well. Given parts of

typebase64Binary (or hexBinary), JAX-WS maps those to parameters of type byte[]. With MTOM, the MIME-ness of the types has all been extracted from the WSDL with the burden placed on the client or server run time to format the content appropriately.

The interface portion of both WSDLs shows that the data type in the operations is base64Binary, which maps to byte[]. In the JAX-RPC Sw/A WSDL, however, you know from the binding that the part types are a MIME image and a MIME octet stream. In the JAX-WS MTOM WSDL, this information is lost. This may seem like a bad thing, but the positive spin is that this completely cleans up the interface. No matter what the binding, the interface is always the same. In fact, the implementors of the client and the server codebases shouldn't be bothered with the notion of whether the parameter is an attachment. That's merely a detail of the SOAP message, and the writers of the WSDL-to-Java mappings have tried their best to abstract the programmer away from the details of the SOAP message.

However, if you really want to know what the MIME type is - if you want to get back to the information you lost - JAX-WS provides support for an attribute that you can inject into an XML

element: expectedContentTypes.

JAX-WS MIME attribute:

<definitions ...> <types> <xsd:schema xmlns:tns="http://attachment.tip/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://attachment.tip/"> <xsd:element name="sendImage" type="tns:sendImage"/>

Page 139: Chapter

<xsd:complexType name="sendImage"> <xsd:sequence> <xsd:element xmlns:ns1="http://www.w3.org/2005/05/xmlmime" ns1:expectedContentTypes="image/*" name="image" type="xsd:base64Binary"/> </xsd:sequence> </xsd:complexType> <xsd:element name="sendImageResponse" type="tns:sendImageResponse"/> <xsd:complexType name="sendImageResponse"> <xsd:sequence/> </xsd:complexType> <xsd:element name="sendOctet" type="tns:sendOctet"/> <xsd:complexType name="sendOctet"> <xsd:sequence> <xsd:element xmlns:ns1="http://www.w3.org/2005/05/xmlmime" ns1:expectedContentTypes="application/octet-stream" name="octet" type="xsd:base64Binary"/> </xsd:sequence> </xsd:complexType> <xsd:element name="sendOctetResponse" type="tns:sendOctetResponse"/> <xsd:complexType name="sendOctetResponse"> <xsd:sequence/> </xsd:complexType> </xsd:schema> </types> ... </definitions>

JAX-WS Java interface mapped from the MIME attribute:

package tip.attachment; import java.awt.Image; import javax.activation.DataHandler; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; import javax.xml.ws.RequestWrapper; import javax.xml.ws.ResponseWrapper; @WebService(name = "AttachmentTip", targetNamespace = "http://attachment.tip/") public interface AttachmentTip { @WebMethod @RequestWrapper(localName = "sendImage", targetNamespace = "http://attachment.tip/", className = "tip.attachment.SendImage") @ResponseWrapper(localName = "sendImageResponse", targetNamespace = "http://attachment.tip/", className = "tip.attachment.SendImageResponse")

Describes the best practices for production and consumption of data for interoperability between WCF web services and Java weclients or between Java web services and WCF web service clients.

Primitives and Wrappers

Java primitive and wrapper classes map to slightly different XML schema representations. Therefore, .NET bindings will vary accordingly.

A Java primitive type and its corresponding wrapper class are shown below.

Java code fragment:

public class StockItem{ public Double wholeSalePrice; public double retailPrice; }

Schema fragment:

<xs:complexType name="stockItem">

Page 140: Chapter

<xs:sequence> <xs:element name="wholeSalePrice" type="xs:double" minOccurs="0"/> <xs:element name="retailPrice" type="xs:double"/> </xs:sequence> </xs:complexType>

.NET C# auto generated code from schema:

public partial class stockItem { private double wholeSalePrice; private bool wholeSalePriceFieldSpecified; private double retailPrice; public double wholeSalePrice { get{ return this.wholeSalePrice;} set{this.wholeSalePrice=value} } public bool wholeSalePriceSpecified { get{ return this.wholeSalePriceFieldSpecified;} set{this.wholeSalePriceFieldSpecified=value} } public double retailPrice { get{ return this.retailPrice;} set{this.retailPrice=value} } }

BigDecimal Type

Limit decimal values to the range and precision of .NET's System.decimal.

java.math.BigDecimal maps to xs:decimal.

.NET maps xs:decimal to System.decimal.

These two data types support different range and precision. java.math.BigDecimal supports arbitrary precision. System.decimal does not. For interoperability use

only values within the range and precision of System.decimal. (See System.decimal.Minvalue and System.decimal.Maxvalueoutside of this range require a customized .NET client.

Java code fragment:

public class RetBigDecimal { private BigDecimal arg0; public BigDecimal getArg0() { return this.arg0; } public void setArg0(BigDecimal arg0) { this.arg0 = arg0; } }

Schema fragment:

<xs:complexType name="retBigDecimal"> <xs:sequence> <xs:element name="arg0" type="xs:decimal" minOccurs="0"/> </xs:sequence> </xs:complexType>

.NET auto generated code from schema

public partial class retBigDecimal{ private decimal arg0Field; private bool arg0FieldSpecified; public decimal arg0 { get { return this.arg0Field;} set { this.arg0Field = value;} }

Page 141: Chapter

public bool arg0Specified { get { return this.arg0FieldSpecified;} set { this.arg0FieldSpecified = value;} } }

XMLGregorianCalendar Type

Use java.xml.datatype.XMLGregorianCalendar instead of java.util.Date and java.util.Calendar.

XMLGregorianCalendar supports the following XML schema calendar

types: xs:date, xs:time, xs:dateTime, xs:gYearMonth, xs:gMonthDay, xs:gYear,xs:gMonth, and xs:gDay. It is statically mapped

to xs:anySimpleType, the common schema type from which all the XML schema calendar types are dervived.

.NET maps xs:anySimpleType to System.string.

java.util.Date and java.util.Calendar map to xs:dateTime, but don't provide as complete XML support as XMLGregorianCalendar

Use the annotation @XmlSchemaType for a strongly typed binding of XMLGregorianCalendar to one of the XML schema calendar types.

Java code fragment:

public class PurchaseOrder { public javax.xml.datatype.XMLGregorianCalendar orderDate; }

Schema fragment:

<xs:complexType name="purchaseOrder"> <xs:sequence> <xs:element name="orderDate" type="xs:anySimpleType" minOccurs="0"/> </xs:sequence> </xs:complexType>

.NET auto generated code from schema:

public partial class purchaseOrder { private string orderDateField; public string orderDate { get { return this.orderDateField; } set { this.orderDateField = value; } } }

Enum Type

A Java enum type maps to an XML schema type constrained by enumeration facets. This, in turn, binds to the .NET type enum type.

Java enum -> xs:simpleType (with enumeration facets) -> .NET enum.

Java code fragment:

public enum USState {MA, NH}

Schema fragment:

<xs:simpleType name="usState"> <xs:restriction base="xs:string"> <xs:enumeration value="NH" /> <xs:enumeration value="MA" /> </xs:restriction>

Page 142: Chapter

</xs:simpleType>

.NET auto generated code from schema:

public enum usState { NH, MA }

Given a scenario, design a Java EE web service using Web Services Design Pattern (Asynchronous Interaction, JMS Bridge, Web SCache, Web Service Broker), and Best Practices.

Asynchronous Interaction

• Server-Side Push Implementation

The server-side push implementation decouples the input and output messages for the interaction. In this implementation, the design is converted so that there are two separate interactions; one from client to server that the client uses to issue its request to the server, and another from server to client that the server uses to notify the client of

1. A business document like a purchase order or invoice in XML format is sent as the SOAP message in the request. 2. The service accepts the document and

a. Does not return any message to the client. This corresponds to a void return type in the Service Endpoint Interface. If due to HTTP issues the client could not receive a successful HTTP 200 message or receives a SOAP Fault, then it is up to the client to retry the invocation or query the service. This retry logic would need to be built into the application layer.

b. Sends a SOAP message back to the client. The contents of the message are dictated by the schema in the WSDL. The message would typically contain aacknowledgement, informing the client that the request is being processed.

3. Once the service receives the message it is placed on a JMS queue for processing at a later time. 4. The Message Driven Beans deployed in the container actively receive and process the message containing the XML business document from the queue.5. The response to the business processing, is also placed on another JMS Queue for dispatch to the client at a later time. 6. Other Message Driven Beans can pick up the responses use the JAX-WS API to make client calls to the callback services on the service consumer's side. The responses to

the business could be another XML document.

• JAX-WS-Based Implementation

The web services interfaces included in the Java EE specification provide support for non-portable asynchronous interactions, but only for JAX-WS-based interactions. JAX

introduces the Dispatch<T> and Provider<T> interfaces that are used to describe the client and server sides to the interaction.

Client-side Dispatch Interface Definition:

// T is the type of the message public interface Dispatch<T> { //synchronous request-response T invoke(T msg); //async request-response Response<T> invokeAsync(T msg); Future<?> invokeAsync(Tmsg, AsyncHandler<T> h); // one-way void invokeOneWay(T msg); }

Page 143: Chapter

Server-side Provider Interface Definition:

// T is the type of the message public interface Provider<T> { T invoke(T msg, Map<String, Object> context); }

Client developer may use asynchronous invocations as defined by the JAX-WS specification. JAX-WS supports asynchronous invocations through generated asynchronous methods on

the Service Endpoint Interface and javax.xml.ws.Dispatch interface. There are two forms of asynchronous invocations in JAX-WS тАУ Polling

o Polling

Client asynchronous polling invocations must be supported by components running in Servlet container, EJB container and Application Client container, since any of these

components can act as JAX- WS clients. Client developers can either use the Service Endpoint Interface orjavax.xml.ws.Dispatch polling invocations.

javax.xml.ws.Dispatch - The invokeAsync method returns a Response that may be polled using the methods inherited

from Future<T> to determine when the operation has completed and to retrieve the results.

SEI - A polling method returns a typed Response<ResponseBean> that may be polled using methods inherited from Future<?>the operation has completed and to retrieve the results:

Service service = ...; StockQuote quoteService = (StockQuote)service.getPort(portName); Response<Float> response = quoteService.getPriceAsync(ticker); while (!response.isDone()) { // do something while we wait } Float quote = response.get();

o Callback

Client asynchronous callback invocations should only be supported by components running in EJB, Servlet container and Application Client container. Client developers can

either use the Service Endpoint Interface or javax.xml.ws.Dispatch to implement asynchronous callback invocations. The callback handler must

implement javax.xml.ws.AsyncHandler interface.

javax.xml.ws.Dispatch - The client supplies an AsyncHandler and the runtime calls the handleResponse method when the results

Page 144: Chapter

of the operation are available. The invokeAsync method returns a wildcard Future (Future<?>) that may be polled to determine when the operation

has completed. The object returned from Future<?>.get() has no standard type. Client code should not attempt to cast the object to any partithis will result in non-portable behavior.

SEI - A callback method takes an additional final parameter that is an instance of a typed AsyncHandler<ResponseBean> and returns a

wildcardFuture<?> that may be polled to determine when the operation has completed. The object returned from Future<?>.get()type. Client code should not attempt to cast the object to any particular type as this will result in non-portable behavior:

StockQuotePortProxy proxy = ... // Set up the callback handler. MyPriceHandler callbackHandler = new MyPriceHandler(); // Make the Web Service call Future<?> response = proxy.getPriceAsync(ticker, callbackHandler); class MyPriceHandler implements AsyncHandler<Float> { ... public void handleResponse(Response<Float> response) { Float price = response.get(); ... } }

JMS Bridge

Provides interoperability between two different JMS implementations.

If the enterprise application is complex enough to run on more than one hardware platform, it is not uncommon for there to be two or more JMS implementations in play, and interoperability then becomes an issue. JMS Bridge promotes vendor independence.

The JMS Bridge pattern suggests keeping the different subsystems using their own JMS implementations, but advocates the introduction of a client into the enterprise application that can relay messages from one JMS implementation to the next. It decouples an abstraction from its implementation so that the two can vary independently.

Page 145: Chapter

Web Service Cache

JAX-WS programming model provides an application handler facility that enables you to manipulate a message on either an inbound or an outbound flow. You can add handlers into the JAXruntime environment to perform additional processing of request and response messages. You can use handlers for a variety of purposes such as caching, capturing and logging information and adding security or other information to a message. Because of the support for additional protocols beyond SOAP, JAX-WS provides two different classifications for handlers.

One type of handler is a logical handler that is protocol independent and can obtain the message in the flow as an extensible markup language (XML) message. The logical handlers operate on

message context properties and message payload. These handlers must implement thejavax.xml.ws.handler.LogicalHandler interface. A logical handler receives

a LogicalMessageContext object from which the handler can get the message information. Logical handlers can exist on both SOAP and XML/HTTP-based configurations.

The second type of handler is a protocol handler. The protocol handlers operate on message context properties and protocol-specific messages. Protocol handlers are limited to SOAP

configurations and must implement the javax.xml.ws.handler.soap.SOAPHandler interface. Protocol handlers receive the message as

a javax.xml.soap.SOAPMessage to read the message data.

The JAX-WS runtime makes no distinction between server-side and client-side handler classes. The runtime does not distinguish between inbound or outbound flow when

a handleMessage(MessageContext) method or handleFault(MessageContext) method for a specific handler is invoked. You must configure the handlers for the server or client, and implement sufficient logic within these methods to detect the inbound or outbound direction of the current message.

To use handlers with Web Services client applications, you must add the @HandlerChain annotation to the Service Endpoint Interface or the generated service class and provide the

handler chain configuration file. The @HandlerChain annotation contains a file attribute that points to a handler chain configuration file that you create. For Web Services client applications, you can also configure the handler chain programmatically using the Binding API. To modify the handlerchain class programmatically, use either the default implementation or a

custom implementation of the HandlerResolver method.

To use handlers with your server application, you must set the @HandlerChain annotation on either the Service Endpoint Interface or the endpoint implementation class, and provide

the associated handler chain configuration file. Handlers for the server are only configured by setting the @HandlerChainannotation on the service endpoint implementation or the implementation class. The handler classes must be included in the deployed artifact.

For both server and client implementations of handlers using the @HandlerChain annotation, you must specify the location of the handler configuration as either a relative path from the annotated file or as an absolute URL. For example:

@HandlerChain(file="../../common/handlers.xml")

or

@HandlerChain(file="http://java.boot.by/handlers.xml")

To create a JAX-WS handler:

1. Determine if you want to implement JAX-WS handlers on the service or the client.

a. Use the default implementation of a handler resolver. The runtime now uses the @HandlerChain annotation and the default implementation

ofHandlerResolver class to build the handler chain. You can obtain the existing handler chain from the Binding, add or remove handlers, and then

return the modified handler chain to the Binding object.

b. To use a custom implementation of a handler resolver, set the custom HandlerResolver class on the Service instance. The runtime uses your custom

implementation of the HandlerResolver class to build the handler chain, and the default runtime implementation is not used. In this scenario,

the @HandlerChain annotation is not read when retrieving the handler chain from the binding after the custom HandlerResolverregistered on the Service instance. You can obtain the existing handler chain from the Binding, add or remove handlers, and then return the modified handler

chain to the Binding object.

2. Configure the client handlers by setting the @HandlerChain annotation on the service instance or Service Endpoint Interface, or you can modify the handler chaprogrammatically to control how the handler chain is built in the runtime. If you choose to modify the handler chain programmatically, then you must determine if you will use the default handler resolver or use a custom implementation of a handler resolver that is registered on the service instance. A service instance uses a handler resolver when creating binding providers. When the binding providers are created, the handler resolver that is registered with a service is used to create a handler chain and the handler chain is subsequently used to configure the binding provider.

3. Configure the server handlers by setting the @HandlerChain annotation on the Service Endpoint Interface or implementation class. When

the@HandlerChain annotation is configured on both the Service Endpoint Interface and the implementation class, the implementation class takes priority.

4. Create the handler chain configuration XML file. You must create a handler chain configuration XML file for the @HandlerChain to reference. 5. Add the handler chain configuration XML file in the class path for the Service Endpoint Interface when configuring the server or client handlers using

the @HandlerChain annotation. You must also include the handler classes contained in the configuration XML file in your class path. 6. Write your handler implementation.

Page 146: Chapter

Web Service Cache pattern:

Opportunities for caching:

1. Client-side transparent to the application cache. 2. Server-side transparent to the application cache. 3. Server-side application-specific cache.

Web Service Broker

A Web Service is a popular way of exposing business services to other applications. The integration of different heterogeneous systems, however, can typically involve incompatibilities and complexities. Furthermore, it is desirable to limit the set of services that are exposed by an application as Web Services. The Web Service Broker pattern uses XML and web protocols to

selectively expose and broker the services of an application. A WebServiceBrokercoordinates the interaction among services, collects responses and performs transactions. It is

typically exposed using a WSDL. The EndpointProcessorclass is the entry point into the Web Service, and processes the client request. The EndpointProcessorinvokes the Web Service through theWebServiceBroker, which brokers to one or more services.

Problem:

• You want to provide access to one or more services using XML and web protocols.

Forces:

• You want to reuse and expose existing services to clients.

• You want to monitor and potentially limit the usage of exposed services, based on your business requirements and system resource usage.

• Your services must be exposed using open standards to enable integration of heterogeneous applications.

• You want to bridge the gap between business requirements and existing service capabilities.

Solution:

• Use a Web Service Broker to expose and broker one or more services in your application to external clients as a Web Service using XML and standard web protocols:

Page 147: Chapter

Consequences:

• Introduces a layer between client and service.

• Existing remote Session Facades need be refactored to support local access.

• Network performance may be impacted due to web protocols.

• Coordinates interactions among one or more services, aggregates responses and may demarcate and compensate transactions.

public void sendImage( @WebParam(name = "image", targetNamespace = "") Image image ); @WebMethod @RequestWrapper(localName = "sendOctet", targetNamespace = "http://attachment.tip/", className = "tip.attachment.SendOctet") @ResponseWrapper(localName = "sendOctetResponse", targetNamespace = "http://attachment.tip/", className = "tip.attachment.SendOctetResponse") public void sendOctet( @WebParam(name = "octet", targetNamespace = "") DataHandler octet ); }

One of the of additional benefits of MTOM is the fact that you can turn it on or off. In the case of Sw/A, if one side or the other doesn't support sending Sw/A attachments, then the contract defined by the WSDL cannot be honored. On the other hand, a client could choose to send data as an MTOM attachment or inline in the SOAP message. No matter what the client chooses, it can still interact with the Web service. MTOM is just an optimization of sending content, not a mandate like Sw/A.

JAX-WS still supports the Sw/A model. By default, JAX-WS maps a Sw/A attachment to a byte[] on the Java interface. To get the mapping you are used to in JAX-RPC, you can use

the enableMIMEContent WSDL binding definition. Listing below shows the JAX-WS version of the Java interface.

Unlike developing a web service provider, creating a web service client application always starts with an existing WSDL file. This process is similar to the process you use to build a service from an existing WSDL file. The WSDL file that the client consumes already contains the WS-* policy assertions (and, in some cases, any value-added WSIT policy assertions that augment Sun's implementation, but can safely be ignored by other implementations). Most of the policy assertions are defined in the WS-* specifications. Sun's implementation processes these standard policy assertions.

Chapter 12. Endpoint Design and Architecture

Page 148: Chapter

Given a scenario, design Web service applications using information models that are either procedure-style or document-style.

• [NONE] blah

Empty

A WSDL document describes a Web service. A WSDL binding describes how the service is bound to a messaging protocol, particularly the SOAP messaging protocol. A WSDL SOAP binding can be either a Remote Procedure Call (RPC) style binding or a document style binding. A SOAP binding can also have an encoded use or a literal use. This gives you four style/use models:

1. RPC/encoded 2. RPC/literal 3. Document/encoded 4. Document/literal

Let's start with the Java method:

public void myMethod(int x, float y);

RPC/encoded

RPC/encoded WSDL for myMethod:

<message name="myMethodRequest"> <part name="x" type="xsd:int"/> <part name="y" type="xsd:float"/> </message> <message name="empty"/> <portType name="PT"> <operation name="myMethod"> <input message="myMethodRequest"/> <output message="empty"/> </operation> </portType> <binding .../>

RPC/encoded SOAP message for myMethod:

<soap:Envelope> <soap:Body> <myMethod> <x xsi:type="xsd:int">5</x> <y xsi:type="xsd:float">5.0</y> </myMethod> </soap:Body> </soap:Envelope>

There are a number of things to notice about the WSDL and SOAP message for this RPC/encoded example:

• Strengths

o The WSDL is about as straightforward as it's possible for WSDL to be.

Page 149: Chapter

o The operation name appears in the message, so the receiver has an easy time dispatching this message to the implementation of the operation.

• Weaknesses

o The type encoding info (such as xsi:type="xsd:int") is usually just overhead which degrades throughput performance.

o You cannot easily validate this message since only the <x ...>5</x> and <y ...>5.0</y> lines

contain things defined in a schema; the rest of the soap:Body contents comes from WSDL definitions.

o Although it is legal WSDL, RPC/encoded is not WS-I compliant.

RPC/literal

The RPC/literal WSDL for this method looks almost the same as the RPC/encoded WSDL (see above). The use in the binding is

changed from encoded toliteral.

RPC/literal WSDL for myMethod:

<message name="myMethodRequest"> <part name="x" type="xsd:int"/> <part name="y" type="xsd:float"/> </message> <message name="empty"/> <portType name="PT"> <operation name="myMethod"> <input message="myMethodRequest"/> <output message="empty"/> </operation> </portType> <binding .../>

RPC/literal SOAP message for myMethod:

<soap:Envelope> <soap:Body> <myMethod> <x>5</x> <y>5.0</y> </myMethod> </soap:Body> </soap:Envelope>

Here are the strengths and weaknesses of RPC/literal approach:

• Strengths

o The WSDL is still about as straightforward as it is possible for WSDL to be.

o The operation name still appears in the message.

o The type encoding info is eliminated.

o RPC/literal is WS-I compliant.

• Weaknesses

o You cannot easily validate this message since only the <x ...>5</x> and <y ...>5.0</y> lines

contain things defined in a schema; the rest of the soap:Body contents comes from WSDL definitions.

Document/encoded

Nobody follows this style. It is not WS-I compliant.

Document/literal

Page 150: Chapter

Document/literal WSDL for myMethod:

<types> <schema> <element name="xElement" type="xsd:int"/> <element name="yElement" type="xsd:float"/> </schema> </types> <message name="myMethodRequest"> <part name="x" element="xElement"/> <part name="y" element="yElement"/> </message> <message name="empty"/> <portType name="PT"> <operation name="myMethod"> <input message="myMethodRequest"/> <output message="empty"/> </operation> </portType> <binding .../>

Document/literal SOAP message for myMethod:

<soap:Envelope> <soap:Body> <xElement>5</xElement> <yElement>5.0</yElement> </soap:Body> </soap:Envelope>

Here are the strengths and weaknesses of Document/literal approach:

• Strengths

o There is no type encoding info.

o You can finally validate this message with any XML validator. Everything within the soap:Body is defined in a schema.

o Document/literal is WS-I compliant, but with restrictions.

• Weaknesses

o The WSDL is getting a bit more complicated. This is a very minor weakness, however, since WSDL is not meant to be read by humans.

o The operation name in the SOAP message is lost. Without the name, dispatching can be difficult, and sometimes impossible.

o WS-I only allows one child of the soap:Body in a SOAP message. As you can see in listing above, this

example's soap:Body has two children.

Document/literal wrapped

Document/literal wrapped WSDL for myMethod:

<types> <schema> <element name="myMethod"> <complexType> <sequence> <element name="x" type="xsd:int"/> <element name="y" type="xsd:float"/> </sequence> </complexType> </element>

Page 151: Chapter

<element name="myMethodResponse"> <complexType/> </element> </schema> </types> <message name="myMethodRequest"> <part name="parameters" element="myMethod"/> </message> <message name="empty"> <part name="parameters" element="myMethodResponse"/> </message> <portType name="PT"> <operation name="myMethod"> <input message="myMethodRequest"/> <output message="empty"/> </operation> </portType> <binding .../>

The WSDL schema now has a wrapper around the parameters.

Document/literal wrapped SOAP message for myMethod:

<soap:Envelope> <soap:Body> <myMethod> <x>5</x> <y>5.0</y> </myMethod> </soap:Body> </soap:Envelope>

Notice that this SOAP message looks like the RPC/literal SOAP message, but there's a subtle difference. In the RPC/literal SOAP message,

the <myMethod>child of <soap:Body> was the name of the operation. In the document/literal wrapped SOAP message,

the <myMethod> clause is the name of the wrapper element which the single input message's part refers to. It just so happens that one of the characteristics of the wrapped pattern is that the name of the input element is the same as the name of the operation. This pattern is a sly way of putting the operation name back into the SOAP message.

These are the basic characteristics of the document/literal wrapped pattern:

• The input message has a single part.

• The part is an element.

• The element has the same name as the operation.

• The element's complex type has no attributes.

Here are the strengths and weaknesses of document/literal wrapped approach:

• Strengths

o There is no type encoding info.

o Everything that appears in the soap:Body is defined by the schema, so you can easily validate this message.

o You have the method name in the SOAP message.

o Document/literal is WS-I compliant, and the wrapped pattern meets the WS-I restriction that the SOAP

message's soap:Body has only one child.

• Weaknesses

o The WSDL is even more complicated.

Reasons to use document/literal non-wrapped

If you have overloaded operations, you cannot use the document/literal wrapped style.

Page 152: Chapter

public void myMethod(int x, float y); public void myMethod(int x);

When you add the wrapped pattern to WSDL, you require an element to have the same name as the operation, and you cannot have two elements with the same name in XML. So you must use the document/literal, non-wrapped style or one of the RPC styles.

Reasons to use RPC/literal

Since the document/literal, non-wrapped style doesn't provide the operation name, there are cases where you'll need to use one of the RPC styles. For instance, say you have the set of methods:

public void myMethod(int x, float y); public void myMethod(int x); public void someOtherMethod(int x, float y);

Now assume that your server receives the document/literal SOAP message. Which method should the server dispatch to? All you know for

sure is that it's not myMethod(int x) because the message has two parameters and this method requires one. It could be either of the other two methods. With the document/literal style, you have no way to know which one.

Instead of the document/literal message, assume that the server receives an RPC/literal message. With this message it's fairly easy for a

server to decide which method to dispatch to. You know the operation name is myMethod, and you know you have two parameters, so it

must be myMethod(int x, float y).

Reasons to use RPC/encoded

The primary reason to prefer the RPC/encoded style is for data graphs. Imagine that you have a binary tree whose nodes are defined:

<complexType name="Node"> <sequence> <element name="name" type="xsd:string"/> <element name="left" type="Node" xsd:nillable="true"/> <element name="right" type="Node" xsd:nillable="true"/> </sequence> </complexType>

With this node definition, you could construct a tree whose root node A points to node B through both its left and right links. The standard

way to send data graphs is to use the href attribute, which is part of the RPC/encoded style:

<A> <name>A</name> <left href="12345"/> <right href="12345"/> </A> <B id="12345"> <name>B</name> <left xsi:nil="true"/> <right xsi:nil="true"/> </B>

Under any literal style, the href attribute is not available, so the graph linkage is lost. You still have a root node, A, which points to a

node B to the left and another node B to the right. These B nodes are equal, but they are not the same node. Data have been duplicated instead of being referenced twice:

<A> <name>A</name> <left> <name>B</name> <left xsi:nil="true"/> <right xsi:nil="true"/>

Page 153: Chapter

</left> <right> <name>B</name> <left xsi:nil="true"/> <right xsi:nil="true"/> </right> </A>

Design a Web service for an asynchronous, document-style process and describe how to refactor a Web service from a synchronous to an asynchronous model.

• [BLUEPRINTS] Chapter 8 - Application Architecture

Refactoring Synchronous to Asynchronous Interactions

Sometimes your application requires an asynchronous Web Service interaction. Web Services that use asynchronous interactions tend to be more responsive and scale better. However, Web Services provide only a synchronous mode of operation, especially when using the HTTP protocol. In your application you can convert this synchronous interaction to an asynchronous request and reply. You may be able to refactor some of the synchronous interactions of a Web Service application to asynchronous interactions.

Figure below illustrates a synchronous interaction. Notice how the client must suspend its processing until the service completes processing of the request and returns a response.

On the other hand, with the asynchronous interaction, the client continues its processing without waiting for the service. In both the synchronous and asynchronous communication figures, the vertical lines represent the passage of time, from top to bottom. The vertical rectangular boxes indicate when the entity (client or service) is busy processing the request or waiting for the other entity to complete processing. In figure below, the open arrowhead indicates asynchronous communication and the dashed vertical line indicates that the entity is free to work on other things while a request is being processed.

Page 154: Chapter

When a component makes a synchronous call to another component, the calling component must wait for the receiving component to finish its processing. If the calling component instead makes the call asynchronously, the caller can proceed with its own work without waiting for the receiving component to do its job.

Below is the list of steps which need to be done to convert a synchronous endpoint to an asynchronous endpoint:

• Change a synchronous request/reply interaction into a request that returns void as the immediate reply.

• Change the client code to send the message request and immediately return.

• Have the client establish a reply address for receiving the response and include this reply address in the request. By including a reply address, the service knows where to send the response message.

• A correlation identifier needs to be established between the request message and the service response message. Both the client and the service use this identifier to associate the request and the reply.

• Refactor the server endpoint to accept the request, send it to a JMS queue for processing later, and immediately return an acknowledgement to the client. The service retains the correlation identifier.

• Have the service processing layer use a message-driven bean to process the received request. When a response is ready, the service sends the response to the reply address. In addition to the results, the response message contains the same correlation identifier so that the service requestor can identify the request to which this response relates.

• Have the client accept the response at a Web Service that it establishes at the reply address.

Page 155: Chapter

The JMS queue stores the messages until the message-driven beans are ready to process them, thereby controlling the rate of delivery. Thus, the component can process the messages without being overwhelmed, which helps the service to scale better.

The policy assertions describe any requirements from the server as well as any optional features the client may use. The WSIT build tools and run-time environment detect the WSDL's policy assertions and configure themselves appropriately, if possible. If an unsupported assertion is found, an error message describing the problem will be displayed.

Typically, you retrieve the WSDL directly from a web service provider using the wsimport tool. The wsimport tool then generates

the corresponding Java source code for the interface described by the WSDL. The Java compiler, javac, is then called to compile the source into class files. The programming code uses the generated classes to access the web service.

<wsp:Policy wsu:Id="AddNumbers_policy"> <wsp:ExactlyOne>

Page 156: Chapter

<wsp:All> <wsaw:UsingAddressing/> <wsrm:RMAssertion> <wsrm:InactivityTimeout Milliseconds="600000"/> <wsrm:AcknowledgementInterval Milliseconds="200"/> </wsrm:RMAssertion> </wsp:All> </wsp:ExactlyOne> </wsp:Policy>

This snippet would be equally valid in either a WSIT configuration file or a web service's WSDL document.