Last Modified: 04/04/2005
Web service client applications may choose to work at the XML message level by using the Dispatch<T>
APIs. The javax.xml.rpc.Dispatch<T>
interface provides support for the dynamic invocation of service endpoint operations.
Four Message Exchange Protocols(MEP) are supported: request-response, one way, asynchronous polling, and callback. Each of these invocation MEPs are required with JAXB data bound java.lang.Object
, javax.xml.transform.Source
, and javax.xml.soap.SOAPMessage
object requests.
The javax.xml.rpc.Service
interface acts as a factory for the creation of Dispatch
instances. In addition, a Dispatch
instance is created in either Service.Mode.PAYLOAD
or Service.Mode.MESSAGE
modes. A javax.xml.soap.SOAPMessage
request can only be used with a Dispatch instance of Service.Mode.MESSAGE
.
Note that the Dispatch<T>
instance simply acts as a conduit for the request. No validation of the message is required to be performed by the implementation, though some may catch errors during request processing. Additionally, Dispatch<T>
has no knowledge of the web service and the WSDL definition. It is up to the client program to supply well-formed XML requests.
Service
instance.The javax.xml.rpc.ServiceFactory
acts as a factory for the creation of Service
instances. When created for use with Dispatch
APIs the Service
created is a non-configured Service
. That is, the Service
has no knowledge of the web service WSDL file other than what the client developer supplies.
The easiest way to create a Service
is show here:
Service serviceFactory = ServiceFactory.newInstance(); Service service = serviceFactory.createService(serviceQName);
Other methods in ServiceFactory
may be used to create a Service
. However, they are not supported in this EA release of JAXRPC 2.0. In these cases, the created service would still be devoid of the WSDL knowledge of the web service types, messages, and operations.
A Dispatch<T>
instance must be bound to a specific port and endpoint before use. The service instance has a createPort(QName portName, URI bindingID, String endpointAddress)
method that the client program can invoke for Dispatch<T>
objects. Ports created using this method can only be used with Dispatch
and Call instances.
Note: The Call
API is not supported in JAXRPC 2.0 EA.
Those developers who have used web service applications in the past are familiar with the port QName
and endpoint parameters of this method. However, what is this BindingID
URI parameter? Currently, the JAXRPC 2.0 Early Draft Specification supports and defines one Binding
URI, that of the SOAP/HTTP Binding. In WSDL this corresponds to the following lines. More may be defined in future versions of the JAXRPC 2.0 specification.
<binding name="BindingName" type="tns:typename"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document|rpc"/>
The creation of the port using the Service
API is shown here:
service.createPort(QName portName, URI new URI(SOAPBinding.SOAP11HTTP_BINDING),String endpointAddress);
Dispatch
instance.The Dispatch
object can be created using either of these two Service
methods:
Dispatch dispatch = service.createDispatch(QName portName, Class clazz, Service.Mode mode); Dispatch dispatch = service.createDispatch(QName portName, JAXBContext jaxbcontext, Service.Mode mode);
For a javax.xml.transform.Source
and JAXB data binding java.lang.Object
Dispatch<T>
can be created in both Service.Mode.PAYLOAD
and Service.Mode.MESSAGE
modes. A javax.xml.soap.SOAPMessage
can only be created in Service.Mode.MESSAGE
mode. The first form of the createDispatch
method is used to create a javax.xml.transform.Source
or javax.xml.soap.SOAPMessage
specific to the Dispatch<T>
instance.
A JAXB object-specific instance can only be created using the second method listed above.
It is important to note that once the Dispatch<T>
instance is created it is static. That is, its Service.Mode
or request type can not be changed. The instance can be reused given the caveat that if it is a JAXB-specific Dispatch<T>
it must be reused with objects known to the same JAXBContext
.
JAXRPCContext
for the request.The Dispatch<T>
interface extends the javax.xml.rpc.BindingProvider
interface. The BindingProvider
interface defines accessor methods for the JAXRPCContext
request and response context. Standard BindingProvider
properties are defined by the JAXRPC 2.0 Early Draft specification and the client program may set and get these properties. The application may also define application-specific properties, but the specification discourages this for portability reasons.
This is the client developer's responsibility. For examples of how to prepare specific request types refer to the Dispatch
sample applications.
Four types of invocation MEPs are supported using the methods below. In methods that produce a response, the type of Object
returned will be of the same type as the request. For example, a SOAPMessage
request will return a SOAPMessage
response.
Object response = dispatch.invoke(T); dispatch.invokeOneway(T); Response<T> response = dispatch.invokeAsync(T); Future<?> response = dispatch.invokeAsync(T, AsyncHandler);
Asynchronous invocations require special consideration. The first form of the invokeAsync
method is a polling method. The response, Response<T>
,returns to the user immediately and may be polled for completion. In the meantime, the client program can do other work.
The javax.xml.rpc.Response<T>
implements the java.util.concurrent.Future<T>
interface that is included in J2SE 5.0. The Response<T>
object returns the actual response via its get
method, which blocks if the response is not ready to be returned.
The Future<T>
interface also has a cancel
method that will attempt to cancel the request invocation if the request is being invoked.
Faults returned from the service or exceptions thrown during the invocation are returned when the Response<T>
get
method is called. Because the execution doesn't occur in the main thread, the exception or fault returned is wrapped in an java.util.concurrent.ExecutionException
. To obtain the actual cause use the getCause
method of ExecutionException
.
For more information on the java.util.concurrent.Future<?>
interface see the J2SE 5.0 documentation.
public interface Response<T>extends java.util.concurrent.Future<T>{ JAXRPCContext getContext(); }
The second form of the invokeAsync
method has a second parameter of type javax.xml.rpc.AsyncHandler
. The purpose of the AsyncHandler
is to get and handle the the response or any fault thrown in an application-specific way. The AsyncHandler
has a method handleResponse(Response<T>)
that takes a javax.xml.rpc.Response<T>
parameter. This method gets the response or any faults and processes them according to behavior defined in the application. Note that it is the responsibility of the client program to implement the asynchronous handler.
class ResponseHandler implements javax.xml.rpc.AsyncHandler{ public handleResponse(Response<T>); }
This form of the asynchronous invocation method returns a Future<?>
object with wildcard type. As in the asynchronous poll invocation, the Future<T>
object can be polled to see if the response is ready. However, calling the get
method will not return the response of the invocation, but an object of indeterminate type.
Examples of synchronous and asynchronous invocations are shown in the Dispatch
samples. For convenience an example of Response
usage is display here:
Response<Source> response = dispatch.invokeAsync(Source); while (!response.isDone()){ //go off and do some work } try { //get the actual result Source result = (javax.xml.transform.Source)response.get(); //do something with the result } catch (ExecutionException ex){ //get the actual cause Throwable cause = ex.getCause(); } catch (InterupptedException ie){ //note interruptions System.out.println("Operation invocation interrupted"); }
Copyright © 2005 Sun Microsystems, Inc. All rights reserved.