Chapter 39. Using Raw XML Messages
Abstract
Dispatch
interface is the client-side interface, and the Provider
interface is the server-side interface.
39.1. Using XML in a Consumer
Abstract
Dispatch
interface is a low-level JAX-WS API that allows you work directly with raw messages. It accepts and returns messages, or payloads, of a number of types including DOM objects, SOAP messages, and JAXB objects. Because it is a low-level API, the Dispatch
interface does not perform any of the message preparation that the higher-level JAX-WS APIs perform. You must ensure that the messages, or payloads, that you pass to the Dispatch
object are properly constructed, and make sense for the remote operation being invoked.
39.1.1. Usage Modes
Overview
Dispatch
objects have two usage modes:
- Message mode
- Message Payload mode (Payload mode)
Dispatch
object determines the amount of detail that is passed to the user level code.
Message mode
Dispatch
object works with complete messages. A complete message includes any binding specific headers and wrappers. For example, a consumer interacting with a service that requires SOAP messages must provide the Dispatch
object's invoke()
method a fully specified SOAP message. The invoke()
method also returns a fully specified SOAP message. The consumer code is responsible for completing and reading the SOAP message's headers and the SOAP message's envelope information.
Dispatch
object uses message mode provide the value java.xml.ws.Service.Mode.MESSAGE
when creating the Dispatch
object. For more information about creating a Dispatch
object see the section called “Creating a Dispatch object”.
Payload mode
Dispatch
object works with only the payload of a message. For example, a Dispatch
object working in payload mode works only with the body of a SOAP message. The binding layer processes any binding level wrappers and headers. When a result is returned from the invoke()
method the binding level wrappers and headers are already striped away, and only the body of the message is left.
Dispatch
object uses payload mode provide the value java.xml.ws.Service.Mode.PAYLOAD
when creating the Dispatch
object. For more information about creating a Dispatch
object see the section called “Creating a Dispatch object”.
39.1.2. Data Types
Overview
Dispatch
objects are low-level objects, they are not optimized for using the same JAXB generated types as the higher level consumer APIs. Dispatch
objects work with the following types of objects:
Using Source objects
Dispatch
object accepts and returns objects that are derived from the javax.xml.transform.Source
interface. Source
objects are supported by any binding, and in either message mode or payload mode.
Source
objects are low level objects that hold XML documents. Each Source
implementation provides methods that access the stored XML documents and then manipulate its contents. The following objects implement the Source
interface:
DOMSource
- Holds XML messages as a Document Object Model(DOM) tree. The XML message is stored as a set of
Node
objects that are accessed using thegetNode()
method. Nodes can be either updated or added to the DOM tree using thesetNode()
method. SAXSource
- Holds XML messages as a Simple API for XML (SAX) object. SAX objects contain an
InputSource
object that holds the raw data and anXMLReader
object that parses the raw data. StreamSource
- Holds XML messages as a data stream. The data stream can be manipulated the same as any other data stream.
Dispatch
object so that it uses generic Source
objects, Apache CXF returns the messages as SAXSource
objects.
Using SOAPMessage objects
Dispatch
objects can use javax.xml.soap.SOAPMessage
objects when the following conditions are true:
- The
Dispatch
object is using the SOAP binding - The
Dispatch
object is using message mode
SOAPMessage
object holds a SOAP message. They contain one SOAPPart
object and zero or more AttachmentPart
objects. The SOAPPart
object contains the SOAP specific portions of the SOAP message including the SOAP envelope, any SOAP headers, and the SOAP message body. The AttachmentPart
objects contain binary data that is passed as an attachment.
Using DataSource objects
Dispatch
objects can use objects that implement the javax.activation.DataSource
interface when the following conditions are true:
- The
Dispatch
object is using the HTTP binding - The
Dispatch
object is using message mode
DataSource
objects provide a mechanism for working with MIME typed data from a variety of sources, including URLs, files, and byte arrays.
Using JAXB objects
Dispatch
objects are intended to be low level APIs that allow you to work with raw messages, they also allow you to work with JAXB objects. To work with JAXB objects a Dispatch
object must be passed a JAXBContext
that can marshal and unmarshal the JAXB objects in use. The JAXBContext
is passed when the Dispatch
object is created.
JAXBContext
object as the parameter to the invoke()
method. You can also cast the returned message into any JAXB object understood by the JAXBContext
object.
JAXBContext
object see Chapter 37, Using A JAXBContext
Object.
39.1.3. Working with Dispatch
Objects
Procedure
Dispatch
object to invoke a remote service the following sequence should be followed:
Creating a Dispatch object
Dispatch
object do the following:
- Create a
Service
object to represent thewsdl:service
element that defines the service on which theDispatch
object will make invocations. See Section 23.2, “Creating a Service Object”. - Create the
Dispatch
object using theService
object'screateDispatch()
method, shown in Example 39.1, “ThecreateDispatch()
Method”.Example 39.1. The
createDispatch()
Methodpublic Dispatch<T> createDispatch(QName portName,
java.lang.Class<T> type,
Service.Mode mode)
throws WebServiceException;NoteIf you are using JAXB objects the method signature forcreateDispatch()
is:public Dispatch<T> createDispatch(QName portName,
javax.xml.bind.JAXBContext context,
Service.Mode mode)
throws WebServiceException;Table 39.1, “Parameters forcreateDispatch()
” describes the parameters for thecreateDispatch()
method.Table 39.1. Parameters for createDispatch() Parameter Description portName
Specifies the QName of the wsdl:port
element that represents the service provider where theDispatch
object will make invocations.type
Specifies the data type of the objects used by theDispatch
object. See Section 39.1.2, “Data Types”.When working with JAXB objects, this parameter specifies theJAXBContext
object used to marshal and unmarshal the JAXB objects.mode
Specifies the usage mode for the Dispatch
object. See Section 39.1.1, “Usage Modes”.
Dispatch
Object” shows the code for creating a Dispatch
object that works with DOMSource
objects in payload mode.
Example 39.2. Creating a Dispatch
Object
package com.fusesource.demo; import javax.xml.namespace.QName; import javax.xml.ws.Service; public class Client { public static void main(String args[]) { QName serviceName = new QName("http://org.apache.cxf", "stockQuoteReporter"); Service s = Service.create(serviceName); QName portName = new QName("http://org.apache.cxf", "stockQuoteReporterPort"); Dispatch<DOMSource> dispatch = s.createDispatch(portName, DOMSource.class, Service.Mode.PAYLOAD); ...
Constructing request messages
Dispatch
objects, requests must be built from scratch. The developer is responsible for ensuring that the messages passed to a Dispatch
object match a request that the targeted service provider can process. This requires precise knowledge about the messages used by the service provider and what, if any, header information it requires.
- The root element of the request is based in the value of the
name
attribute of thewsdl:operation
element corresponding to the operation being invoked.WarningIf the service being invoked uses doc/literal bare messages, the root element of the request is based on the value of thename
attribute of thewsdl:part
element referred to by thewsdl:operation
element. - The root element of the request is namespace qualified.
- If the service being invoked uses rpc/literal messages, the top-level elements in the request will not be namespace qualified.ImportantThe children of top-level elements may be namespace qualified. To be certain you must check their schema definitions.
- If the service being invoked uses rpc/literal messages, none of the top-level elements can be null.
- If the service being invoked uses doc/literal messages, the schema definition of the message determines if any of the elements are namespace qualified.
Synchronous invocation
Dispatch
object's invoke()
method shown in Example 39.3, “The Dispatch.invoke()
Method”.
Example 39.3. The Dispatch.invoke()
Method
T invoke(T msg)
throws WebServiceException;
invoke()
method are determined when the Dispatch
object is created. For example if you create a Dispatch
object using createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE)
, both the response and the request are SOAPMessage
objects.
JAXBContext
object can marshal and unmarshal. Also, the response and the request can be different JAXB objects.
Dispatch
Object” shows code for making a synchronous invocation on a remote service using a DOMSource
object.
Example 39.4. Making a Synchronous Invocation Using a Dispatch
Object
// Creating a DOMSource Object for the request DocumentBuilder db = DocumentBuilderFactory.newDocumentBuilder(); Document requestDoc = db.newDocument(); Element root = requestDoc.createElementNS("http://org.apache.cxf/stockExample", "getStockPrice"); root.setNodeValue("DOW"); DOMSource request = new DOMSource(requestDoc); // Dispatch disp created previously DOMSource response = disp.invoke(request);
Asynchronous invocation
Dispatch
objects also support asynchronous invocations. As with the higher level asynchronous APIs discussed in Chapter 38, Developing Asynchronous Applications, Dispatch
objects can use both the polling approach and the callback approach.
invokeAsync()
method returns a Response<t>
object that can be polled to see if the response has arrived. Example 39.5, “The Dispatch.invokeAsync()
Method for Polling” shows the signature of the method used to make an asynchronous invocation using the polling approach.
Example 39.5. The Dispatch.invokeAsync()
Method for Polling
Response <T> invokeAsync(T msg)
throws WebServiceException;
invokeAsync()
method takes an AsyncHandler
implementation that processes the response when it is returned. Example 39.6, “The Dispatch.invokeAsync()
Method Using a Callback” shows the signature of the method used to make an asynchronous invocation using the callback approach.
Example 39.6. The Dispatch.invokeAsync()
Method Using a Callback
Future<?> invokeAsync(T msg,
AsyncHandler<T> handler)
throws WebServiceException;
invoke()
method, the type of the response and the type of the request are determined when you create the Dispatch
object.
Oneway invocation
Dispatch
object's invokeOneWay()
. Example 39.7, “The Dispatch.invokeOneWay()
Method” shows the signature for this method.
Example 39.7. The Dispatch.invokeOneWay()
Method
void invokeOneWay(T msg)
throws WebServiceException;
Dispatch
object is created. For example if the Dispatch
object is created using createDispatch(portName, DOMSource.class, Service.Mode.PAYLOAD)
, then the request is packaged into a DOMSource
object.
JAXBContext
object can marshal and unmarshal.
Dispatch
Object” shows code for making a oneway invocation on a remote service using a JAXB object.
Example 39.8. Making a One Way Invocation Using a Dispatch
Object
// Creating a JAXBContext and an Unmarshaller for the request JAXBContext jbc = JAXBContext.newInstance("org.apache.cxf.StockExample"); Unmarshaller u = jbc.createUnmarshaller(); // Read the request from disk File rf = new File("request.xml"); GetStockPrice request = (GetStockPrice)u.unmarshal(rf); // Dispatch disp created previously disp.invokeOneWay(request);