Network Deployment (Distributed operating systems), v8.0 > Develop and deploying applications > Develop web services - Addressing (WS-Addressing) > Enable Web Services Addressing support for JAX-WS applications
Invoke JAX-WS web services asynchronously
Java API for XML-Based Web Services (JAX-WS) provides support for invoking web services using an asynchronous client invocation. JAX-WS provides support for both a callback and polling model when calling web services asynchronously. Both the callback model and the polling model are available on the Dispatch client and the Dynamic Proxy client.
Develop a JAX-WS Dynamic Proxy or Dispatch client. When developing Dynamic Proxy clients, after you generate the portable client artifacts from a WSDL file using the wsimport command, the generated service endpoint interface (SEI) does not have asynchronous methods included in the interface. Use JAX-WS bindings to add the asynchronous callback or polling methods on the interface for the Dynamic Proxy client.
To enable asynchronous mappings, you can add the jaxws:enableAsyncMapping binding declaration to the WSDL file. For more information on adding binding customizations to generate an asynchronous interface, see chapter 8 of the JAX-WS specification.
When you run the wsimport tool and enable asynchronous invocation through the use of the JAX-WS enableAsyncMapping binding declaration, ensure that the corresponding response message your WSDL file does not contain parts. When a response message does not contain parts, the request acts as a two-way request, but the actual response that is sent back is empty. The wsimport tool does not correctly handle a void response.
To avoid this scenario, you can remove the output message from the operation which makes your operation a one-way operation or you can add a <wsdl:part> to your message. For more information on the usage, syntax and parameters for the wsimport tool, see the wsimport command for JAX-WS applications documentation.
An asynchronous invocation of a web service sends a request to the service endpoint and then immediately returns control to the client program without waiting for the response to return from the service. JAX-WS asynchronous web service clients consume web services using either the callback approach or the polling approach. Using a polling model, a client can issue a request and receive a response object that 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. The handleResponse() method of the handler is called when the result is available. 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. Polling invocations are valid from EJB clients or Java EE application clients. Callback invocations are valid only from Java EE application clients.
Use the callback asynchronous invocation model
To implement an asynchronous invocation that uses the callback model, the client provides an AsyncHandler callback handler to accept and process the inbound response object. The client callback handler implements the javax.xml.ws.AsyncHandler interface, which contains the application code that is run when an asynchronous response is received from the server. The javax.xml.ws.AsyncHandler interface contains the handleResponse(java.xml.ws.Response) method that is called after the run time has received and processed the asynchronous response from the server. The response is delivered to the callback handler in the form of a javax.xml.ws.Response object. The response object returns the response content when the get() method is called. Additionally, if an error was received, then an exception is returned to the client during that call. The response method is then invoked according to the threading model used by the executor method, java.util.concurrent.Executor on the client's java.xml.ws.Service instance that was used to create the Dynamic Proxy or Dispatch client instance. The executor is used to invoke any asynchronous callbacks registered by the application. Use the setExecutor and getExecutor methods to modify and retrieve the executor configured for your service.
Use the polling asynchronous invocation model
Use the polling model, a client can issue a request and receive a response object that can subsequently be polled to determine if the server has responded. When the server responds, the actual response can then be retrieved. The response object returns the response content when the get() method is called. The client receives an object of type javax.xml.ws.Response from the invokeAsync method. That Response object is used to monitor the status of the request to the server, determine when the operation has completed, and to retrieve the response results.
Use an asynchronous message exchange
By default, asynchronous client invocations do not have asynchronous behavior of the message exchange pattern on the wire. The programming model is asynchronous; however, the exchange of request or response messages with the server is not asynchronous. To use an asynchronous message exchange, the com.ibm.websphere.webservices.use.async.mep property must be set on the client request context with a boolean value of true. When this property is enabled, the messages exchanged between the client and server are different from messages exchanged synchronously. With an asynchronous exchange, the request and response messages have WS-Addressing headers added that provide additional routing information for the messages. Another major difference between asynchronous and synchronous message exchange is that the response is delivered to an asynchronous listener that then delivers that response back to the client. For asynchronous exchanges, there is no timeout that is sent to notify the client to stop listening for a response. To force the client to stop waiting for a response, issue a Response.cancel() method on the object returned from a polling invocation or a Future.cancel() method on the object returned from a callback invocation. The cancel response does not affect the server when processing a request. (Windows) Avoid trouble: The location of the asynchronous listener is sent to the server, so that the service can reply to the client. On Windows operating systems, the local host name is used by default, because it is compatible with Dynamic Host Configuration Protocol (DHCP). However, if the server cannot resolve the host name, the client application does not receive replies from the target service. For example, a client application is hosted on the workstation myhost.bar.com. In the following SOAP message header, the client application sends the short name myhost as its host details. Unless the target server can resolve myhost to myhost.bar.com, subsequent replies do not reach the client application:
<soapenv:Header> <wsa:To>http://target.bar.com:81/LiteSecurityService/SecurityService </wsa:To> <wsa:ReplyTo> <wsa:Address>http://myhost:2146/axis2/services/LiteSecurityService. WSRMServicePort/AnonOutInOp?IBMwebservicesID=922A5DC38A337C4CEF1168347862705 </wsa:Address> </wsa:ReplyTo> <wsa:MessageID>urn:uuid:922A5DC38A337C4CEF1168347862403 </wsa:MessageID> <wsa:Action>getEndpointReference </wsa:Action> </soapenv:Header>To resolve this issue, configure the client to send the location details for the asynchronous listener in IP format, by adding the following system property to the Java virtual machine. Note that by transmitting the IP address, you lose the benefits of DHCP.-Dcom.ibm.websphere.webservices.transportEPRInIPAddr=yes
Procedure
- Determine to implement the callback method or the polling method for the client to asynchronously invoke the web service.
- (Optional) Configure the client request context. Add the
com.ibm.websphere.webservices.use.async.mepproperty to the request context to enable asynchronous messaging for the web services client. Using this property requires that the service endpoint supports WS-Addressing which is supported by default for the application server. The following example demonstrates how to set this property:Map <String, Object> rc = ((BindingProvider) port).getRequestContext(); rc.put("com.ibm.websphere.webservices.use.async.mep", Boolean.TRUE);
- To implement the asynchronous callback method, perform the following steps.
- Find the asynchronous callback method on the SEI or javax.xml.ws.Dispatch interface. For an SEI, the method name ends in Async and has one more parameter than the synchronous method of type javax.xml.ws.AsyncHandler. The invokeAsync(Object, AsyncHandler) method is the one used on the Dispatch interface.
- (Optional) Add the service.setExecutor methods to the client application. Adding the executor methods gives the client control of the scheduling methods for processing the response. You can also choose to use the java.current.Executors class factory to obtain packaged executors or implement your own executor class. See the JAX-WS specification for more information on using executor class methods with your client.
- Implement the javax.xml.ws.AsyncHandler interface. The javax.xml.ws.AsyncHandler interface only has the handleResponse(javax.xml.ws.Response) method. The method must contain the logic for processing the response or possibly an exception. The method is called after the client run time has received and processed the asynchronous response from the server.
- Invoke the asynchronous callback method with the parameter data and the callback handler.
- The handleResponse(Response) method is invoked on the callback object when the response is available. The Response.get() method is called within this method to deliver the response.
- To implement the polling method,
- Find the asynchronous polling method on the SEI or javax.xml.ws.Dispatch interface. For an SEI, the method name ends in Async and has a return type of javax.xml.ws.Response. The invokeAsync(Object) method is used on the Dispatch interface.
- Invoke the asynchronous polling method with the parameter data.
- The client receives the object type, javax.xml.ws.Response, used to monitor the status of the request to the server. The isDone() method indicates whether the invocation has completed. When the isDone() method returns a value of true, call the get() method to retrieve the response object.
- Use the cancel() method for the callback or polling method if the client needs to stop waiting for a response from the service. If the cancel() method is invoked by the client, the endpoint continues to process the request. However, the wait and response processing for the client is stopped.
Results
You have enabled your JAX-WS web service client to asynchronously invoke and consume web services. See the JAX-WS specification for additional information regarding the asynchronous client APIs.
Example
The following example illustrates a web service interface with methods for asynchronous requests from the client.
@WebService public interface CreditRatingService { // Synchronous operation. Score getCreditScore(Customer customer); // Asynchronous operation with polling. Response <Score> getCreditScoreAsync(Customer customer); // Asynchronous operation with callback. Future <?> getQuoteAsync(Customer customer, AsyncHandler <Score> handler); }
Use the callback method
The callback method requires a callback handler that is shown in the following example. When using the callback procedure, after a request is made, the callback handler is responsible for handling the response. The response value is a response or possibly an exception. The Future <?> method represents the result of an asynchronous computation and is checked to see if the computation is complete. When you want the application to find out if the request is completed, invoke the Future.isDone() method. Note that the Future.get() method does not provide a meaningful response and is not similar to the Response.get() method. CreditRatingService svc = ...; Future <?> invocation = svc.getCreditScoreAsync(customerTom, new AsyncHandler <Score>() { public void handleResponse ( Response <Score> response) { score = response.get(); // process the request... } } );
Use the polling method
The following example illustrates an asynchronous polling client: CreditRatingService svc = ...; Response <Score> response = svc.getCreditScoreAsync(customerTom); while (!response.isDone()) { // Do something while we wait. } score = response.get();
JAX-WS
JAX-WS client programming model
Implement static JAX-WS web services clients
Generate Java artifacts for JAX-WS applications from a WSDL file
Develop a dynamic client using JAX-WS APIs
Related
Web services specifications and APIs
Java API for XML Web Services (JAX-WS) API documentation
Java API for XML Web Services (JAX-WS) API User's Guide documentation