Usage Modes
Overview
Dispatch
objects have two usage modes:
...
The usage mode you specify for a Dispatch
object determines the amount of detail is passed to the user level code.
Message mode
In message mode, a 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 would need to provide the Dispatch
object's invoke()
method a fully specified SOAP message. The invoke()
method will also return 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.
...
You specify that a Dispatch
object uses message mode by providing the value java.xml.ws.Service.Mode.MESSAGE
when creating the Dispatch object.
Payload mode
In payload mode, also called message payload mode, a 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 invoke()
the binding level wrappers and headers are already striped away and only the body of the message is left.
Tip |
---|
When working with a binding that does not use special wrappers, such as the Artix ESB XML binding, payload mode and message mode provide the same results. |
You specify that a Dispatch
object uses payload mode by providing the value java.xml.ws.Service.Mode.PAYLOAD
when creating the Dispatch
object.
Data Types
Overview
Dispatch
objects, because they are low-level objects, 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:
javax.xml.transform.Source
javax.xml.soap.SOAPMessage
javax.activation.DataSource
- JAXB
Using Source
objects
A Dispatch
object can accept and return objects that are derived from the javax.xml.transform.Source
interface. Source objects are low level objects that hold XML documents. Each Source
implementation provides methods that access the stored XML documents and manipulate its contents. The following objects implement the Source
interface:
DOMSource
SAXSource
StreamSource
Info When using
Source
objects the developer is responsible for ensuring that all required binding specific wrappers are added to the message. For example, when interacting with a service expecting SOAP messages, the developer must ensure that the required SOAP envelope is added to the outgoing request and that the SOAP envelope's contents are correct.
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.
Using DataSource
objects
Dispatch
objects can use objects that implement the javax.activation.DataSource
interface when the following conditions are true:
...
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
While Dispatch
objects are intended to be low level API that allows 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 knows how to marshal and unmarshal the JAXB objects in use. The JAXBContext
is passed when the Dispatch
object is created.
You can pass any JAXB object understood by the 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.
Working with Dispatch
Objects
Procedure
To use a Dispatch object to invoke a remote service you do the following:
- Create a
Dispatch
object. - Construct a request message.
- Call the proper
invoke()
method. - Parse the response message.
Creating a Dispatch
object
To create a Dispatch
object do the following:
...
Parameter | Description |
---|---|
portName | Specifies the QName of the |
type | Specifies the data type of the objects used by the |
mode | Specifies the usage mode for the |
The code bellow below creates a Dispatch
object that works with DOMSource
objects in payload mode.
Code Block |
---|
package com.ionamycompany.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
When working with 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.
...
For more information about how services use XML messages see the WS-I Basic Profile.
Synchronous invocation
For consumers that make synchronous invocations that generate a response, you use the Dispatch
object's invoke()
method shown bellow.
Code Block |
---|
T invoke(T msg) throws WebServiceException; |
...
Code Block |
---|
// 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 4, Dispatch
objects can use both the polling approach and the callback approach.
...
Code Block |
---|
Response <T> invokeAsync(T msg) throws WebServiceException; |
...
Code Block |
---|
Future<?> invokeAsync(T msg, AsyncHandler<T> handler) throws WebServiceException; |
Note |
---|
As with the synchronous |
Oneway invocation
When a request does not generate a response, you make remote invocations using the Dispatch
object's invokeOneWay()
.
Code Block |
---|
void invokeOneWay(T msg) throws WebServiceException; |
...
Code Block |
---|
// Creating a JAXBContext and an Unmarshaller for the request JAXBContext jbc = JAXBContext.newInstance("orgcom.apache.cxfmycompany.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); |
Operation Determination
When using a Dispatch
client with a WSDL file, the operation name will be set under one of the following cases.
- The javax.xml.ws.handler.MessageContext.WSDL_OPERATION property of the request context is set with the operation QName.
- The addressing feature is enabled (in the bus or at the endpoint) and there is a matching operation to the payload element.
- The "find.dispatch.operation" property of the request context is set to Boolean.TRUE and there is a matching operation to the payload element. This property is not set by default.Determining the correct operation will affect the processing such as setting the correct SOAPAction or WS-Addressing's Action.