The following sections describe how to use JWS files to implement asynchronous features. The first four sections describe how to implement these features separately. Typically, however, programmers use these features together; see Using the Asynchronous Features Together for more information.
Web Service reliable messaging is a framework whereby an application running in one application server can reliably invoke a Web Service running on another application server, assuming that both servers implement the WS-ReliableMessaging specification. Reliable is defined as the ability to guarantee message delivery between the two Web Services.
Note: | Web Services reliable messaging works between any two application servers that implement the WS-ReliableMessaging specification. In this document, however, it is assumed that the two application servers are WebLogic Server instances. |
WebLogic Web Services conform to the WS-ReliableMessaging specification (February 2005), which describes how two Web Services running on different application servers can communicate reliably in the presence of failures in software components, systems, or networks. In particular, the specification describes an interoperable protocol in which a message sent from a source endpoint (or client Web Service) to a destination endpoint (or Web Service whose operations can be invoked reliably) is guaranteed either to be delivered, according to one or more delivery assurances, or to raise an error.
A reliable WebLogic Web Service provides the following delivery assurances:
See the WS-ReliableMessaging specification for detailed documentation about the architecture of Web Service reliable messaging. Using Web Service Reliable Messaging: Main Steps describes how to create the reliable and client Web Services and how to configure the two WebLogic Server instances to which the Web Services are deployed.
Note: | Web Services reliable messaging is not supported with the JMS transport feature. |
WebLogic Web Services use WS-Policy files to enable a destination endpoint to describe and advertise its Web Service reliable messaging capabilities and requirements. The WS-Policy specification provides a general purpose model and syntax to describe and communicate the policies of a Web service.
These WS-Policy files are XML files that describe features such as the version of the supported WS-ReliableMessaging specification, the source endpoint’s retransmission interval, the destination endpoint’s acknowledgment interval, and so on.
You specify the names of the WS-Policy files that are attached to your Web Service using the @Policy
JWS annotation in your JWS file. Use the @Policies
annotation to group together multiple @Policy
annotations. For reliable messaging, you specify these annotations only at the class level.
WebLogic Server includes two simple WS-Policy files that you can specify in your JWS file if you do not want to create your own WS-Policy files:
DefaultReliability.xml
—Specifies typical values for the reliable messaging policy assertions, such as inactivity timeout of 10 minutes, acknowledgement interval of 200 milliseconds, and base retransmisstion interval of 3 seconds. See DefaultReliability.xml WS-Policy File for the actual WS-Policy file.LongRunningReliability.xml
—Similar to the preceding default reliable messaging WS-Policy file, except that it specifies a much longer activity timeout interval (24 hours.) See LongRunningReliability.xml WS-Policy File for the actual WS-Policy file.You cannot change these pre-packaged files, so if their values do not suit your needs, you must create your own WS-Policy file.
See Creating the Web Service Reliable Messaging WS-Policy File for details about creating your own WS-Policy file if you do not want to one included with WebLogic Server. See Web Service Reliable Messaging Policy Assertion Reference, for reference information about the reliable messaging policy assertions.
<?xml version="1.0"?>
<wsp:Policy
xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm/policy"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:beapolicy="http://www.bea.com/wsrm/policy"
>
<wsrm:RMAssertion >
<wsrm:InactivityTimeout
Milliseconds="600000" />
<wsrm:BaseRetransmissionInterval
Milliseconds="3000" />
<wsrm:ExponentialBackoff />
<wsrm:AcknowledgementInterval
Milliseconds="200" />
<beapolicy:Expires Expires="P1D" optional="true"/>
</wsrm:RMAssertion>
</wsp:Policy>
<?xml version="1.0"?>
<wsp:Policy
xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm/policy"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:beapolicy="http://www.bea.com/wsrm/policy"
>
<wsrm:RMAssertion >
<wsrm:InactivityTimeout
Milliseconds="86400000" />
<wsrm:BaseRetransmissionInterval
Milliseconds="3000" />
<wsrm:ExponentialBackoff />
<wsrm:AcknowledgementInterval
Milliseconds="200" />
<beapolicy:Expires Expires="P1M" optional="true"/>
</wsrm:RMAssertion>
</wsp:Policy>
Configuring reliable messaging for a WebLogic Web Service requires standard JMS tasks such as creating JMS servers and Store and Forward (SAF) agents, as well as Web Service-specific tasks, such as adding additional JWS annotations to your JWS file. Optionally, you create WS-Policy files that describe the reliable messaging capabilities of the reliable Web Service if you do not use the pre-packaged ones.
If you are using the WebLogic client APIs to invoke a reliable Web Service, the client application must run on WebLogic Server. Thus, configuration tasks must be performed on both the source WebLogic Server instance on which the Web Service that includes client code to invoke the reliable Web Service reliably is deployed, as well as the destination WebLogic Server instance on which the reliable Web Service itself is deployed.
The following procedure describes how to create a reliable Web Service, as well as a client Web Service that in turn invokes an operation of the reliable Web Service reliably. The procedure shows how to create the JWS files that implement the two Web Services from scratch; if you want to update existing JWS files, use this procedure as a guide. The procedure also shows how to configure the source and destination WebLogic Server instances.
It is assumed that you have created a WebLogic Server instance where you have set up an Ant-based development environment and that you have a working build.xml
file to which you can add targets for running the jwsc
Ant task and deploying the generated reliable Web Service. It is further assumed that you have a similar setup for another WebLogic Server instance that hosts the client Web Service that invokes the Web Service reliably. For more information, see:
This is the WebLogic Server instance to which the reliable Web Service is deployed.
See Configuring the Destination WebLogic Server Instance.
This is the WebLogic Server instance to which the client Web Service that invokes the reliable Web Service is deployed.
See Configuring the Source WebLogic Server Instance.
See Creating the Web Service Reliable Messaging WS-Policy File for details about creating your own WS-Policy file.
See Programming Guidelines for the Reliable JWS File.
build.xml file
to include a call to the jwsc
Ant task which will compile the reliable JWS file into a Web Service.
See Running the jwsc WebLogic Web Services Ant Task for general information about using the jwsc
task.
prompt> ant build-mainService deploy-mainService
See Programming Guidelines for the JWS File That Invokes a Reliable Web Service.
build.xml
file that builds the client Web Service.See Updating the build.xml File for a Client of a Reliable Web Service.
prompt> ant build-clientService deploy-clientService
Configuring the WebLogic Server instance on which the reliable Web Service is deployed involves configuring JMS and store and forward (SAF) resources.
You can either configure these resources yourself, or you can use the Configuration Wizard to extend the WebLogic Server domain using a Web Services-specific extension template. Using the Configuration Wizard greatly simplifies the required configuration steps; for details, see Configuring Your Domain For Web Services Features.
If, however, you prefer to configure the resources yourself, use the following high-level procedure which lists the tasks and then points to the Administration Console Online Help for details on performing the tasks.
See Invoking the Administration Console for instructions on the URL that invokes the Administration Console.
See Create file stores.
See Create JMS servers.
Take note of the JNDI name you define for the JMS queue because you will later use it when you program the JWS file that implements your reliable Web Service.
See Create JMS modules and Create queues.
If you are using the Web Service reliable messaging feature in a cluster, you must:
Configuring the WebLogic Server instance on which the client Web Service is deployed involves configuring JMS and store and forward (SAF) resources.
You can either configure these resources yourself, or you can use the Configuration Wizard to extend the WebLogic Server domain using a Web Services-specific extension template. Using the Configuration Wizard greatly simplifies the required configuration steps; for details, see Configuring Your Domain For Web Services Features.
If, however, you prefer to configure the resources yourself, use the following high-level procedure which lists the tasks and then points to the Administration Console Online Help for details on performing the tasks.
See Invoking the Administration Console for instructions on the URL that invokes the Administration Console.
See Create file stores.
See Create JMS servers.
Be sure when you create the SAF agent that you set the Agent Type field to Both
to enable both sending and receiving agents.
A WS-Policy file is an XML file that contains policy assertions that comply with the WS-Policy specification. In this case, the WS-Policy file contains Web Service reliable messaging policy assertions.
You can use one of the two default reliable messaging WS-Policy files included in WebLogic Server; these files are adequate for most use cases. However, because these files cannot be changed, if they do not suit your needs, you must create your own. See Use of WS-Policy Files for Web Service Reliable Messaging Configuration for a description of the included WS-Policy files. The remainder of this section describes how to create your own WS-Policy file.
The root element of the WS-Policy file is <Policy>
and it should include the following namespace declarations for using Web Service reliable messaging policy assertions:
<wsp:Policy
xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:beapolicy="http://www.bea.com/wsrm/policy">
You wrap all Web Service reliable messaging policy assertions inside of a <wsrm:RMAssertion>
element. The assertions that use the wsrm:
namespace are standard ones defined by the
WS-ReliableMessaging specification. The assertions that use the beapolicy:
namespace are WebLogic-specific. See Web Service Reliable Messaging Policy Assertion Reference, for details.
All Web Service reliable messaging assertions are optional, so only set those whose default values are not adequate. The order in which the assertions appear is important. You can specify the following assertions; the order they appear in the following list is the order in which they should appear in your WS-Policy file:
<wsrm:InactivityTimeout>
—Number of milliseconds, specified with the Milliseconds
attribute, which defines an inactivity interval. After this amount of time, if the destination endpoint has not received a message from the source endpoint, the destination endpoint may consider the sequence to have terminated due to inactivity. The same is true for the source endpoint. By default, sequences never timeout. <wsrm:BaseRetransmissionInterval>
—Interval, in milliseconds, that the source endpoint waits after transmitting a message and before it retransmits the message if it receives no acknowledgment for that message. Default value is set by the SAF agent on the source endpoint’s WebLogic Server instance.<wsrm:ExponentialBackoff>
—Specifies that the retransmission interval will be adjusted using the exponential backoff algorithm. This element has no attributes. <wsrm:AcknowledgmentInterval>
—Maximum interval, in milliseconds, in which the destination endpoint must transmit a stand-alone acknowledgement. The default value is set by the SAF agent on the destination endpoint’s WebLogic Server instance.<beapolicy:Expires>
—Amount of time after which the reliable Web Service expires and does not accept any new sequence messages. The default value is to never expire. This element has a single attribute, Expires
, whose data type is an
XML Schema duration type. For example, if you want to set the expiration time to one day, use the following: <beapolicy:Expires Expires="P1D" />
.<beapolicy:QOS>
—Delivery assurance level, as described in Using Web Service Reliable Messaging. The element has one attribute, QOS
, which you set to one of the following values: AtMostOnce
, AtLeastOnce
, or ExactlyOnce
. You can also include the InOrder
string to specify that the messages be in order. The default value is ExactlyOnce InOrder
. This element is typically not set. The following example shows a simple Web Service reliable messaging WS-Policy file:
<?xml version="1.0"?>
<wsp:Policy
xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm/policy"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:beapolicy="http://www.bea.com/wsrm/policy"
>
<wsrm:RMAssertion>
<wsrm:InactivityTimeout
Milliseconds="600000" />
<wsrm:BaseRetransmissionInterval
Milliseconds="500" />
<wsrm:ExponentialBackoff />
<wsrm:AcknowledgementInterval
Milliseconds="2000" />
</wsrm:RMAssertion>
</wsp:Policy>
This section describes how to create the JWS file that implements the reliable Web Service.
The following JWS annotations are used in the JWS file that implements a reliable Web Service:
@weblogic.jws.Policy
—Required. See Using the @Policy Annotation.@javax.jws.Oneway
—Required only if you are using Web Service reliable messaging on its own, without also using the asynchronous request-response feature. See Using the @Oneway Annotation and Using the Asynchronous Features Together.@weblogic.jws.BufferQueue
—Optional. See Using the @BufferQueue Annotation.@weblogic.jws.ReliabilityBuffer
—Optional. See Using the @ReliabilityBuffer AnnotationThe following example shows a simple JWS file that implements a reliable Web Service; see the explanation after the example for coding guidelines that correspond to the Java code in bold.
package examples.webservices.reliable;
import javax.jws.WebMethod;
import javax.jws.WebService;import javax.jws.Oneway;
import weblogic.jws.WLHttpTransport;
import weblogic.jws.ReliabilityBuffer;
import weblogic.jws.BufferQueue;
import weblogic.jws.Policy;
/**
* Simple reliable Web Service.
*/
@WebService(name="ReliableHelloWorldPortType",
serviceName="ReliableHelloWorldService")
@WLHttpTransport(contextPath="ReliableHelloWorld",
serviceUri="ReliableHelloWorld",
portName="ReliableHelloWorldServicePort")
@Policy(uri="ReliableHelloWorldPolicy.xml",
direction=Policy.Direction.both,
attachToWsdl=true)
@BufferQueue(name="webservices.reliable.queue")
public class ReliableHelloWorldImpl {
@WebMethod()@Oneway()
@ReliabilityBuffer(retryCount=10, retryDelay="10 seconds")
public void helloWorld(String input) {
System.out.println(" Hello World " + input);
}
}
In the example, the ReliableHelloWorldPolicy.xml
file is attached to the Web Service at the class level, which means that the policy file is applied to all public operations of the Web Service. The policy file is applied only to the request Web Service message (as required by the reliable messaging feature) and it is attached to the WSDL file.
The JMS queue that WebLogic Server uses internally to enable the Web Service reliable messaging has a JNDI name of webservices.reliable.queue
, as specified by the @BufferQueue
annotation.
The helloWorld()
method has been marked with both the @WebMethod
and @Oneway
JWS annotations, which means it is a public operation called helloWorld
. Because of the @Policy
annotation, the operation can be invoked reliably. The Web Services runtime attempts to deliver reliable messages to the service a maximum of 10 times, at 10-second intervals, as described by the @ReliabilityBuffer
annotation. The message may require re-delivery if, for example, the transaction is rolled back or otherwise does not commit.
Use the @Policy
annotation in your JWS file to specify that the Web Service has a WS-Policy file attached to it that contains reliable messaging assertions.
See Use of WS-Policy Files for Web Service Reliable Messaging Configuration for descriptions of the two WS-Policy files (DefaultReliability.xml
and LongRunningReliability.xml
) included in WebLogic Server that you can use instead of writing your own.
You must follow these requirements when using the @Policy
annotation for Web Service reliable messaging:
Use the uri
attribute to specify the build-time location of the policy file, as follows:
@Policy(uri="ReliableHelloWorldPolicy.xml",
direction=Policy.Direction.both,
attachToWsdl=true)
The example shows that the ReliableHelloWorldPolicy.xml
file is located in the same directory as the JWS file.
policy:
prefix along with the name and path of the policy file. This syntax tells the jwsc
Ant task at build-time not to look for an actual file on the file system, but rather, that the Web Service will retrieve the WS-Policy file from WebLogic Server at the time the service is deployed. Use this syntax when specifying one of the pre-packaged WS-Policy files or when specifying a WS-Policy file that is packaged in a shared J2EE library. Note: | Shared J2EE libraries are useful when you want to share a WS-Policy file with multiple Web Services that are packaged in different Enterprise applications. As long as the WS-Policy file is located in the META-INF/policies or WEB-INF/policies directory of the shared J2EE library, you can specify the policy file in the same way as if it were packaged in the same archive at the Web Service. See
Creating Shared J2EE Libraries and Optional Packages for information on creating libraries and setting up your environment so the Web Service can find the policy files. |
http:
prefix along with the URL, as shown in the following example:@Policy(uri="http://someSite.com/policies/mypolicy.xml"
direction=Policy.Direction.both,
attachToWsdl=true)
You can also set the attachToWsd
attribute of the @Policy
annotation to specify whether the policy file should be attached to the WSDL file that describes the public contract of the Web Service. Typically you want to publicly publish the policy so that client applications know the reliable messaging capabilities of the Web Service. For this reason, the default value of this attribute is true
.
If you plan on invoking the reliable Web Service operation synchronously (or in other words, not using the asynchronous request-response feature), then the implementing method is required to be annotated with the @Oneway
annotation to specify that the method is one-way. This means that the method cannot return a value, but rather, must explicitly return void
.
Conversely, if the method is not annotated with the @Oneway
annotation, then you must invoke it using the asynchronous request-response feature. If you are unsure how the operation is going to be invoked, consider creating two flavors of the operation: synchronous and asynchronous.
See Invoking a Web Service Using Asynchronous Request-Response and Using the Asynchronous Features Together.
Use the @BufferQueue
annotation to specify the JNDI name of the JMS queue which WebLogic Server uses to store reliable messages internally. The JNDI name is the one you configured when creating a JMS queue in step 4 in Configuring the Destination WebLogic Server Instance.
The @BufferQueue
annotation is optional; if you do not specify it in your JWS file then WebLogic Server uses a queue with a JNDI name of weblogic.wsee.DefaultQueue
. You must, however, still explicitly create a JMS queue with this JNDI name using the Administration Console.
Use this annotation to specify the number of times WebLogic Server should attempt to deliver the message from the JMS queue to the Web Service implementation (default 3) and the amount of time that the server should wait in between retries (default 5 seconds).
Use the retryCount
attribute to specify the number of retries and the retryDelay
attribute to specify the wait time. The format of the retryDelay
attribute is a number and then one of the following strings:
For example, to specify a retry count of 20 and a retry delay of two days, use the following syntax:
@ReliabilityBuffer(retryCount=20, retryDelay="2 days")
If you are using the WebLogic client APIs, you must invoke a reliable Web Service from within a Web Service; you cannot invoke a reliable Web Service from a stand-alone client application.
The following example shows a simple JWS file for a Web Service that invokes a reliable operation from the service described in Programming Guidelines for the Reliable JWS File; see the explanation after the example for coding guidelines that correspond to the Java code in bold.
package examples.webservices.reliable;
import java.rmi.RemoteException;
import javax.jws.WebMethod;
import javax.jws.WebService;
import weblogic.jws.WLHttpTransport;import weblogic.jws.ServiceClient;
import weblogic.jws.ReliabilityErrorHandler;
import examples.webservices.reliable.ReliableHelloWorldPortType;
import weblogic.wsee.reliability.ReliabilityErrorContext;
import weblogic.wsee.reliability.ReliableDeliveryException;
@WebService(name="ReliableClientPortType",
serviceName="ReliableClientService")
@WLHttpTransport(contextPath="ReliableClient",
serviceUri="ReliableClient",
portName="ReliableClientServicePort")
public class ReliableClientImpl
{
@ServiceClient(
serviceName="ReliableHelloWorldService",
portName="ReliableHelloWorldServicePort")
private ReliableHelloWorldPortType port;
@WebMethod
public void callHelloWorld(String input, String serviceUrl)
throws RemoteException {
port.helloWorld(input);
System.out.println(" Invoked the ReliableHelloWorld.helloWorld operation reliably." );
}
@ReliabilityErrorHandler(target="port")
public void onReliableMessageDeliveryError(ReliabilityErrorContext ctx) {
ReliableDeliveryException fault = ctx.getFault();
String message = null;
if (fault != null) {
message = ctx.getFault().getMessage();
}
String operation = ctx.getOperationName();
System.out.println("Reliable operation " + operation + " may have not invoked. The error message is " + message);
}
}
Follow these guidelines when programming the JWS file that invokes a reliable Web Service; code snippets of the guidelines are shown in bold in the preceding example:
@ServiceClient
and @ReliabitliyErrorHandler
JWS annotations:import weblogic.jws.ServiceClient;
import weblogic.jws.ReliabilityErrorHandler;
<clientgen>
child element of the jwsc
Ant task, of the port type of the reliable Web Service you want to invoke. The stub package is specified by the packageName
attribute of <clientgen>
, and the name of the stub is determined by the WSDL of the invoked Web Service.import examples.webservices.reliable.ReliableHelloWorldPortType;
import weblogic.wsee.reliability.ReliabilityErrorContext;
import weblogic.wsee.reliability.ReliableDeliveryException;
@ServiceClient
JWS annotation to specify the name and port of the reliable Web Service you want to invoke. You specify this annotation at the field-level on a private variable, whose data type is the JAX-RPC port type of the Web Service you are invoking. @ServiceClient(
serviceName="ReliableHelloWorldService",
portName="ReliableHelloWorldServicePort")
private ReliableHelloWorldPortType port;
@ServiceClient
annotation, invoke the reliable operation:
port.helloWorld(input);
Because the operation has been marked one-way, it does not return a value.
@weblogic.jws.ReliabilityErrorHandler
annotation:@ReliabilityErrorHandler(target="port")
public void onReliableMessageDeliveryError(ReliabilityErrorContext ctx) {
ReliableDeliveryException fault = ctx.getFault();
String message = null;
if (fault != null) {
message = ctx.getFault().getMessage();
}
String operation = ctx.getOperationName();
System.out.println("Reliable operation " + operation + " may have not invoked. The error message is " + message);
}
This method takes ReliabilityErrorContext
as its single parameter and returns void
.
See weblogic.jws.ReliabilityErrorHandler for details about programming this error-handling method.
When programming the client Web Service, be sure you do not:
@ReliabilityErrorHandler
) or use any reliable messaging assertions in the associated WS-Policy files.wsdlLocation
attribute of the @ServiceClient
annotation. This is because the runtime retrieval of the specified WSDL might not succeed, thus it is better to let WebLogic Server use a local WSDL file instead.WebLogic Server provides a utility class for use with the Web Service Reliable Messaging feature. Use this class to perform common tasks such as set configuration options, get the sequence id, and terminate a reliable sequence. Some of these tasks are performed in the reliable Web Service, some are performed in the Web Service that invokes the reliable Web Service.
See weblogic.wsee.reliability.WsrmUtils for details.
To update a build.xml
file to generate the JWS file that invokes the operation of a reliable Web Service, add taskdefs
and a build-reliable-client
targets that look something like the following; see the description after the example for details:
<taskdef name="jwsc"
classname="weblogic.wsee.tools.anttasks.JwscTask" />
<target name="build-reliable-client">
<jwsc
enableAsyncService="true"
srcdir="src"
destdir="${client-ear-dir}" >
<jws file="examples/webservices/reliable/ReliableClientImpl.java">
<clientgen
wsdl="http://${wls.destination.host}:${wls.destination.port}/ReliableHelloWorld/ReliableHelloWorld?WSDL"
packageName="examples.webservices.reliable"/>
</jws>
</jwsc>
</target>
Use the taskdef
Ant task to define the full classname of the jwsc
Ant tasks.
Update the jwsc
Ant task that compiles the client Web Service to include a <clientgen>
child element of the <jws>
element so as to generate and compile the JAX-RPC stubs for the deployed ReliableHelloWorld
Web Service. The jwsc
Ant task automatically packages them in the generated WAR file so that the client Web Service can immediately access the stubs. You do this because the ReliableClientImpl
JWS file imports and uses one of the generated classes.
WebLogic Server supports production redeployment, which means that you can deploy a new version of an updated reliable WebLogic Web Service alongside an older version of the same Web Service.
WebLogic Server automatically manages client connections so that only new client requests are directed to the new version. Clients already connected to the Web Service during the redeployment continue to use the older version of the service until they complete their work, at which point WebLogic Server automatically retires the older Web Service. If the client is connected to a reliable Web Service, its work is considered complete when the existing reliable messaging sequence is explicitly ended by the client or because of a time-out.
For additional information about production redployment and Web Service clients, see Client Considerations When Redeploying a Web Service .
When you invoke a Web Service synchronously, the invoking client application waits for the response to return before it can continue with its work. In cases where the response returns immediately, this method of invoking the Web Service might be adequate. However, because request processing can be delayed, it is often useful for the client application to continue its work and handle the response later on, or in other words, use the asynchronous request-response feature of WebLogic Web Services.
You invoke a Web Service asynchronously only from a client running in a WebLogic Web Service, never from a stand alone client application. The invoked Web Service does not change in any way, thus you can invoke any deployed Web Service (both WebLogic and non-WebLogic) asynchronously as long as the application server that hosts the Web Service supports the WS-Addressing specification.
When implementing asynchronous request-response in your client, rather than invoking the operation directly, you invoke an asynchronous flavor of the same operation. (This asynchronous flavor of the operation is automatically generated by the jwsc
Ant task.) For example, rather than invoking an operation called getQuote
directly, you would invoke getQuoteAsync
instead. The asynchronous flavor of the operation always returns void
, even if the original operation returns a value. You then include methods in your client that handle the asynchronous response or failures when it returns later on. You put any business logic that processes the return value of the Web Service operation invoke or a potential failure in these methods. You use both naming conventions and JWS annotations to specify these methods to the JWS compiler. For example, if the asynchronous operation is called getQuoteAsync
, then these methods might be called onGetQuoteAsyncResponse
and onGetQuoteAsyncFailure
.
Note: | For information about using asynchronous request-response with other asynchronous features, such as Web Service reliable messaging or buffering, see Using the Asynchronous Features Together. This section describes how to use the asynchronous request-response feature on its own. |
Note: | The asynchronous request-response feature works only with HTTP; you cannot use it with the HTTPS or JMS transport. |
The following procedure describes how to create a client Web Service that asynchronously invokes an operation in a different Web Service. The procedure shows how to create the JWS file that implements the client Web Service from scratch; if you want to update an existing JWS file, use this procedure as a guide.
For clarity, it is assumed in the procedure that:
It is further assumed that you have set up an Ant-based development environment and that you have a working build.xml
file to which you can add targets for running the jwsc
Ant task and deploying the generated service. See Common Web Services Use Cases and Examples, Iterative Development of WebLogic Web Services, and Programming the JWS File.
StockQuoteClientService
Web Service.See Writing the Asynchronous JWS File.
build.xml
file to compile the JWS file that implements the StockQuoteClientService
. You will add a <clientgen>
child element to the jwsc
Ant task so as to automatically generate the asynchronous flavor of the Web Service operations you are invoking.See Updating the build.xml File When Using Asynchronous Request-Response.
StockQuoteClientService
:prompt> ant build-clientService
StockQuoteClientService
Web Service as usual.
When you invoke the StockQuoteClientService
Web Service, which in turn invokes the StockQuoteService
Web Service, the second invoke will be asynchronous rather than synchronous.
The following example shows a simple JWS file that implements a Web Service called StockQuoteClient
that has a single method, asyncOperation
, that in turn asynchronously invokes the getQuote
method of the StockQuote
service. The Java code in bold is described Coding Guidelines for Invoking a Web Service Asynchronously. See Example of a Synchronous Invoke to see how the asynchronous invoke differs from a synchronous invoke of the same operation.
package examples.webservices.async_req_res;
import weblogic.jws.WLHttpTransport;
import weblogic.jws.ServiceClient;
import weblogic.jws.AsyncResponse;
import weblogic.jws.AsyncFailure;
import weblogic.wsee.async.AsyncPreCallContext;
import weblogic.wsee.async.AsyncCallContextFactory;
import weblogic.wsee.async.AsyncPostCallContext;
import javax.jws.WebService;
import javax.jws.WebMethod;
import examples.webservices.async_req_res.StockQuotePortType;
import java.rmi.RemoteException;
@WebService(name="StockQuoteClientPortType",
serviceName="StockQuoteClientService",
targetNamespace="http://examples.org/")
@WLHttpTransport(contextPath="asyncClient",
serviceUri="StockQuoteClient",
portName="StockQuoteClientServicePort")
/**
* Client Web Service that invokes the StockQuote Service asynchronously.
*/
public class StockQuoteClientImpl {
@ServiceClient(wsdlLocation="http://localhost:7001/async/StockQuote?WSDL",
serviceName="StockQuoteService", portName="StockQuote")
private StockQuotePortType port;
@WebMethod
public void asyncOperation (String symbol) throws RemoteException {
AsyncPreCallContext apc = AsyncCallContextFactory.getAsyncPreCallContext();
apc.setProperty("symbol", symbol);
try {port.getQuoteAsync(apc, symbol );
System.out.println("in getQuote method of StockQuoteClient WS");
} catch (RemoteException re) {
System.out.println("RemoteException thrown");
throw new RuntimeException(re);
}
}
@AsyncResponse(target="port", operation="getQuote")
public void onGetQuoteAsyncResponse(AsyncPostCallContext apc, int quote) {
System.out.println("-------------------");
System.out.println("Got quote " + quote );
System.out.println("-------------------");
}
@AsyncFailure(target="port", operation="getQuote")
public void onGetQuoteAsyncFailure(AsyncPostCallContext apc, Throwable e) {
System.out.println("-------------------");
e.printStackTrace();
System.out.println("-------------------");
}
}
The following guidelines for invoking an operation asynchronously correspond to the Java code shown in bold in the example described in Writing the Asynchronous JWS File. These guidelines are in addition to the standard ones for creating JWS files. See Example of a Synchronous Invoke to see how the asynchronous invoke differs from a synchronous invoke of the same operation.
To invoke an operation asynchronously in your JWS file:
import weblogic.jws.ServiceClient;
import weblogic.jws.AsyncResponse;
import weblogic.jws.AsyncFailure;
jwsc
Ant task, of the port type of the Web Service you want to invoke. The stub package is specified by the packageName
attribute of the <clientgen>
child element of jwsc
, and the name of the stub is determined by the WSDL of the invoked Web Service.import examples.webservices.async_req_res.StockQuotePortType;
import weblogic.wsee.async.AsyncCallContextFactory;
import weblogic.wsee.async.AsyncPreCallContext;
import weblogic.wsee.async.AsyncPostCallContext;
The AsyncPreCallContext
and AsyncPostCallContext
APIs describe asynchronous contexts that you can use for a variety of reasons in your Web Service: to set a property in the pre-context so that the method that handles the asynchronous response can distinguish between different asynchronous calls; to set and get contextual variables, such as the name of the user invoking the operation, their password, and so on; to get the name of the JAX-RPC stub that invoked a method asynchronously; and to set a time-out interval on the context.
See Javadocs for additional reference information about these APIs.
@ServiceClient
JWS annotation to specify the WSDL, name, and port of the Web Service you will be invoking asynchronously. You specify this annotation at the field-level on a variable, whose data type is the JAX-RPC port type of the Web Service you are invoking. @ServiceClient(
wsdlLocation="http://localhost:7001/async/StockQuote?WSDL",
serviceName="StockQuoteService",
portName="StockQuote")
private StockQuotePortType port;
When you annotate a variable (in this case, port
) with the @ServiceClient
annotation, the Web Services runtime automatically initializes and instantiates the variable, preparing it so that it can be used to invoke another Web Service asynchronously.
getQuote
operation asynchronously, get a pre-call asynchronous context using the context factory:AsyncPreCallContext apc =
AsyncCallContextFactory.getAsyncPreCallContext();
setProperty
method of the pre-call context to create a property whose name and value is the same as the parameter to the getQuote
method:apc.setProperty("symbol", symbol);
@ServiceClient
annotation, invoke the operation (in this case, getQuote
). Instead of invoking it directly, however, invoke the asynchronous flavor of the operation, which has Async
added on to the end of its name. The asynchronous flavor always returns void
. Pass the asynchronous context as the first parameter:port.getQuoteAsync(apc, symbol);
on
Operationname
AsyncResponse
, where Operationname
refers to the name of the operation, with initial letter always capitalized. The method must return void
, and have two parameters: the post-call asynchronous context and the return value of the operation you are invoking. Annotate the method with the @AsyncResponse
JWS annotation; use the target
attribute to specify the variable whose datatype is the JAX-RPC stub and the operation
attribute to specify the name of the operation you are invoking asynchronously. Inside the body of the method, put the business logic that processes the value returned by the operation.@AsyncResponse(target="port", operation="getQuote")
public void onGetQuoteAsyncResponse(AsyncPostCallContext apc,
int quote) {
System.out.println("-------------------");
System.out.println("Got quote " + quote );
System.out.println("-------------------");
}
on
Operationname
AsyncFailure
, where Operationname
refers to the name of the operation, with initial letter capitalized. The method must return void
, and have two parameters: the post-call asynchronous context and a Throwable
object, the superclass of all exceptions to handle any type of exception thrown by the invoked operation. Annotate the method with the @AsyncFailure
JWS annotation; use the target
attribute to specify the variable whose datatype is the JAX-RPC stub and the operation
attribute to specify the name of the operation you are invoking asynchronously. Inside the method, you can determine the exact nature of the exception and write appropriate Java code.@AsyncFailure(target="port", operation="getQuote")
public void onGetQuoteAsyncFailure(AsyncPostCallContext apc,
Throwable e) {
System.out.println("-------------------");
e.printStackTrace();
System.out.println("-------------------");
}
Note: | You are not required to use the @AsyncResponse and @AsyncFailure annotations, although it is a good practice because it clears up any ambiguity and makes your JWS file clean and understandable. However, in the rare use case where you want one of the onXXX methods to handle the asynchronous response or failure from two (or more) stubs that are invoking operations from two different Web Services that have the same name, then you should explicitly NOT use these annotations. Be sure that the name of the onXXX methods follow the correct naming conventions exactly, as described above. |
The following example shows a JWS file that invokes the getQuote
operation of the StockQuote
Web Service synchronously. The example is shown only so you can compare it with the corresponding asynchronous invoke shown in Writing the Asynchronous JWS File.
package examples.webservices.async_req_res;
import weblogic.jws.WLHttpTransport;
import weblogic.jws.ServiceClient;
import javax.jws.WebService;
import javax.jws.WebMethod;
import java.rmi.RemoteException;
@WebService(name="SyncClientPortType",
serviceName="SyncClientService",
targetNamespace="http://examples.org/")
@WLHttpTransport(contextPath="syncClient",
serviceUri="SyncClient",
portName="SyncClientPort")
/**
* Normal service-to-service client that invokes StockQuote service
* synchronously.
*/
public class SyncClientImpl {
@ServiceClient(wsdlLocation="http://localhost:7001/async/StockQuote?WSDL",
serviceName="StockQuoteService", portName="StockQuote")
private StockQuotePortType port;
@WebMethod
public void nonAsyncOperation(String symbol) throws RemoteException {
int quote = port.getQuote(symbol);
System.out.println("-------------------");
System.out.println("Got quote " + quote );
System.out.println("-------------------");
}
}
To update a build.xml
file to generate the JWS file that invokes a Web Service operation asynchronously, add taskdefs
and a build-clientService
target that looks something like the following; see the description after the example for details:
<taskdef name="jwsc"
classname="weblogic.wsee.tools.anttasks.JwscTask" />
<target name="build-clientService">
<jwsc
enableAsyncService="true"
srcdir="src"
destdir="${clientService-ear-dir}" >
<jws file="examples/webservices/async_req_res/StockQuoteClientImpl.java" >
<clientgen
wsdl="http://${wls.hostname}:${wls.port}/async/StockQuote?WSDL"
packageName="examples.webservices.async_req_res"/>
</jws>
</jwsc>
</target>
Use the taskdef
Ant task to define the full classname of the jwsc
Ant tasks.
Update the jwsc
Ant task that compiles the client Web Service to include a <clientgen>
child element of the <jws>
element so as to generate and compile the JAX-RPC stubs for the deployed StockQuote
Web Service. The jwsc
Ant task automatically packages them in the generated WAR file so that the client Web Service can immediately access the stubs. By default, the jwsc
Ant task in this case generates both synchronous and asynchronous flavors of the Web Service operations in the JAX-RPC stubs. You do this because the StockQuoteClientImpl
JWS file imports and uses one of the generated classes.
By default, every WebLogic Server instance deploys an internal asynchronous Web Service that handes the asynchronous request-response feature. To specify that you do not want to deploy this internal service, start the WebLogic Server instance using the -Dweblogic.wsee.skip.async.response=true
Java system property.
One reason for disabling the asynchronous service is if you use a WebLogic Server instance as a Web proxy to a WebLogic cluster. In this case, asynchronous messages will never get to the cluster, as required, because the asynchronous service on the proxy server consumes them instead. For this reason, you must disable the asynchronous service on the proxy server using the system property.
For details on specifying Java system properties to configure WebLogic Server, see Specifying Java Options for a WebLogic Server Instance.
Callbacks notify a client of your Web Service that some event has occurred. For example, you can notify a client when the results of that client's request are ready, or when the client’s request cannot be fulfilled.
When you expose method as a standard public operation in your JWS file (by using the @WebMethod
annotation), the client sends a SOAP message to the Web Service to invoke the operation. When you add a callback to a Web Service, however, you define a message that the Web Service sends back to the client Web Service, notifying the client of an event that has occurred. So exposing a method as a public operation and defining a callback are completely symmetrical processes, with opposite recipients.
WebLogic Server automatically routes the SOAP message from client invoke to the target Web Service. In order to receive callbacks, however, the client must be operating in an environment that provides the same services. This typically means the client is a Web Service running on a Web server. If the client does not meet these requirements, it is likely not capable of receiving callbacks from your Web Service.
The protocol and message format used for callbacks is always the same as the protocol and message format used by the conversation start method that initiated the current conversation. If you attempt to override the protocol or message format of a callback, an error is thrown.
To implement callbacks, you must create or update the following three Java files:
jwsc
Ant task automatically generates an implementation of the interface. The implementation simply passes a message from the target Web Service back to the client Web Service. The generated Web Service is deployed to the same WebLogic Server that hosts the client Web Service.
In the example in this section, the callback interface is called CallbackInterface
. The interface defines a single callback method called callbackOperation()
.
In the example, this Web Service is called TargetService
and it defines a single standard method called targetOperation()
.
In the example, this Web Service is called CallbackClient
and the method that is automatically invoked when it receives a callback is called callbackHandler()
. The method that invokes TargetService
in the standard way is called clientOperation()
.
The following graphic shows the flow of messages:
clientOperation()
method of the CallbackClient
Web Service, running in one WebLogic Server instance, explicitly invokes the targetOperation()
operation of the TargetService
. The TargetService
service might be running in a separate WebLogic Server instance.TargetService.targetOperation()
method explicitly invokes the callbackOperation()
operation of the CallbackInterface
, which implements the callback service. The callback service is deployed to the WebLogic Server which hosts the client Web Service. jwsc
-generated implementation of the CallbackInterface.callbackOperation()
method simply sends a message back to the CallbackClient
Web Service. The client Web Service includes a method callbackHandler()
that handles this message.The procedure in this section describes how to program and compile the three JWS files that are required to implement callbacks: the target Web Service, the client Web Service, and the callback interface. The procedure shows how to create the JWS files from scratch; if you want to update existing JWS files, you can also use this procedure as a guide.
It is assumed that you have set up an Ant-based development environment and that you have a working build.xml
file to which you can add targets for running the jwsc
Ant task and deploying the Web Services. For more information, see Common Web Services Use Cases and Examples, Iterative Development of WebLogic Web Services, and Programming the JWS File.
See Programming Guidelines for Target Web Service.
Note: | The JWS file that implements the target Web Service invokes one or more callback methods of the callback interface. However, the step that describes how to program the callback interface comes later in this procedure. For this reason, programmers typically program the three JWS files at the same time, rather than linearly as implied by this procedure. The steps are listed in this order for clarity only. |
build.xml
file to include a call to the jwsc
Ant task to compile the target JWS file into a Web Service. See Running the jwsc WebLogic Web Services Ant Task.
prompt> ant build-mainService
See Deploying and Undeploying WebLogic Web Services.
See Programming Guidelines for the Callback Client Web Service.
See Programming Guidelines for the Callback Interface.
build.xml
file that builds the client Web Service. The jwsc
Ant task that builds the client Web Service also implicitly generates the callback Web Service from the callback interface file.See Updating the build.xml File for the Client Web Service.
prompt> ant build-clientService
The following example shows a simple JWS file that implements the target Web Service; see the explanation after the example for coding guidelines that correspond to the Java code in bold.
package examples.webservices.callback;
import weblogic.jws.WLHttpTransport;import weblogic.jws.Callback;
import javax.jws.WebService;
import javax.jws.WebMethod;
@WebService(name="CallbackPortType",
serviceName="TargetService",
targetNamespace="http://examples.org/")
@WLHttpTransport(contextPath="callback",
serviceUri="TargetService",
portName="TargetServicePort")
/**
* callback service
*/
public class TargetServiceImpl {
@Callback
CallbackInterface callback;
@WebMethod
public void targetOperation (String message) {
callback.callbackOperation (message);
}
}
Follow these guidelines when programming the JWS file that implements the target Web Service. Code snippets of the guidelines are shown in bold in the preceding example.
import weblogic.jws.Callback;
@weblogic.jws.Callback
JWS annotation to specify that a variable is a callback, which means that you can use the annotated variable to send callback events back to a client Web Service that invokes an operation of the TargetService
Web Service. The data type of the variable is the callback interface, which in this case is called CallbackInterface
.@Callback
CallbackInterface callback;
TargetService
, use the annotated variable to invoke one of the callback methods of the callback interface, which in this case is called callbackOperation()
:callback.callbackOperation (message);
See JWS Annotation Reference, for additional information about the JWS annotations discussed in this section.
The following example shows a simple JWS file for a client Web Service that invokes the target Web Service described in Programming Guidelines for Target Web Service; see the explanation after the example for coding guidelines that correspond to the Java code in bold.
package examples.webservices.callback;
import weblogic.jws.WLHttpTransport;import weblogic.jws.ServiceClient;
import weblogic.jws.CallbackMethod;
import weblogic.jws.security.CallbackRolesAllowed;
import weblogic.jws.security.SecurityRole;
import javax.jws.WebService;
import javax.jws.WebMethod;
import examples.webservices.callback.CallbackPortType;
import java.rmi.RemoteException;
@WebService(name="CallbackClientPortType",
serviceName="CallbackClientService",
targetNamespace="http://examples.org/")
@WLHttpTransport(contextPath="callbackClient",
serviceUri="CallbackClient",
portName="CallbackClientPort")
public class CallbackClientImpl {
@ServiceClient(
wsdlLocation="http://localhost:7001/callback/TargetService?WSDL",
serviceName="TargetService",
portName="TargetServicePort")
@CallbackRolesAllowed(@SecurityRole(role="mgr", mapToPrincipals="joe"))
private CallbackPortType port;
@WebMethod
public void clientOperation (String message) {
try {
port.targetOperation(message);
}
catch (RemoteException e) {
e.printStackTrace();
}
}@CallbackMethod(target="port", operation="callbackOperation")
@CallbackRolesAllowed(@SecurityRole(role="engineer", mapToPrincipals="shackell"))
public void callbackHandler(String msg) {
System.out.println (msg);
}
}
Follow these guidelines when programming the JWS file that invokes the target Web Service; code snippets of the guidelines are shown in bold in the preceding example:
import weblogic.jws.ServiceClient;
import weblogic.jws.CallbackMethod;
import weblogic.jws.security.CallbackRolesAllowed;
import weblogic.jws.security.SecurityRole;
jwsc
Ant task. The stub package is specified by the packageName
attribute of the <clientgen>
child element of <jws>
, and the name of the stub is determined by the WSDL of the invoked Web Service.import examples.webservices.callback.CallbackPortType;
@ServiceClient
JWS annotation to specify the WSDL, name, and port of the target Web Service you want to invoke. You specify this annotation at the field-level on a private variable, whose data type is the JAX-RPC port type of the Web Service you are invoking. @ServiceClient(
wsdlLocation="http://localhost:7001/callback/TargetService?WSDL",
serviceName="TargetService",
portName="TargetServicePort")
@CallbackRolesAllowed(@SecurityRole(role="mgr", mapToPrincipals="joe"))
private CallbackPortType port;
The preceding code also shows how to use the optional @CallbackRolesAllowed
annotation to specify the list of @SecurityRoles
that are allowed to invoke the callback methods.
@ServiceClient
annotation, invoke an operation of the target Web Service. This operation in turn will invoke a callback method of the callback interface:port.targetOperation(message);
Annotate the method with the @CallbackMethod
annotation to specify that this method handles callback messages. Use the target
attribute to specify the name of the JAX-RPC port for which you want to receive callbacks (in other words, the variable you previously annotated with @ServiceClient
). Use the operation
attribute to specify the name of the callback method in the callback interface from which this method will handle callback messages.
@CallbackMethod(target="port", operation="callbackOperation")
@CallbackRolesAllowed(@SecurityRole(role="engineer", mapToPrincipals="shackell"))
public void callbackHandler(String msg) {
System.out.println (msg);
}
The preceding code also shows how to use the optional @CallbackRolesAllowed
annotation to further restrict the security roles that are allowed to invoke this particular callback method.
See JWS Annotation Reference, for additional information about the JWS annotations discussed in this section.
The callback interface is also a JWS file that implements a Web Service, except for one big difference: instead of using the standard @javax.jws.WebService
annotation to specify that it is a standard Web Service, you use the WebLogic-specific @weblogic.jws.CallbackService
to specify that it is a callback service. The attributes of @CallbackService
are a restricted subset of the attributes of @WebService
.
Follow these restrictions on the allowed data types and JWS annotations when programming the JWS file that implements a callback service:
@weblogic.jws.CallbackService
.Holder
classes (user-defined data types that implement the javax.xml.rpc.holders.Holder
interface).
The following example shows a simple callback interface file that implements a callback Web Service. The target Web Service, described in Programming Guidelines for Target Web Service, explicitly invokes a method in this interface. The jwsc
-generated implementation of the callback interface then automatically sends a message back to the client Web Service that originally invoked the target Web Service; the client service is described in Programming Guidelines for the Callback Client Web Service. See the explanation after the example for coding guidelines that correspond to the Java code in bold.
package examples.webservices.callback;
import weblogic.jws.CallbackService;
import javax.jws.Oneway;
import javax.jws.WebMethod;
@CallbackService
public interface CallbackInterface {
@WebMethod
@Onewaypublic void callbackOperation (String msg);
}
Follow these guidelines when programming the JWS interface file that implements the callback Web Service. Code snippets of the guidelines are shown in bold in the preceding example.
import weblogic.jws.CallbackService;
@CallbackService
annotation to specify that the JWS file implements a callback service:@CallbackService
public interface CallbackInterface {
jwsc
Ant task.public void callbackOperation (String msg);
Note: | Although the example shows the callback method returning void and annotated with the @Oneway annotation, this is not a requirement. |
See JWS Annotation Reference, for additional information about the JWS annotations discussed in this section.
When you run the jwsc Ant task against the JWS file that implements the client Web Service, the task implicitly also generates the callback Web Service, as described in this section.
You update a build.xml
file to generate a client Web Service that invokes the target Web Service by adding taskdefs
and a build-clientService
target that looks something like the following example. See the description after the example for details.
<taskdef name="jwsc"
classname="weblogic.wsee.tools.anttasks.JwscTask" />
<target name="build-clientService">
<jwsc
srcdir="src"
destdir="${clientService-ear-dir}" >
<jws file="examples/webservices/callback/CallbackClientImpl.java" >
<clientgen
wsdl="http://${wls.hostname}:${wls.port}/callback/TargetService?WSDL"
packageName="examples.webservices.callback"
serviceName="TargetService" />
</jws>
</jwsc>
</target>
Use the taskdef
Ant task to define the full classname of the jwsc
Ant tasks.
Update the jwsc
Ant task that compiles the client Web Service to include a <clientgen>
child element of the <jws>
element so as to generate and compile the JAX-RPC stubs for the deployed TargetService
Web Service. The jwsc
Ant task automatically packages them in the generated WAR file so that the client Web Service can immediately access the stubs. You do this because the CallbackClientImpl
JWS file imports and uses one of the generated classes.
Because the WSDL of the target Web Service includes an additional <service>
element that describes the callback Web Service (which the target Web Service invokes), the <clientgen>
child element of the jwsc
Ant task also generates and compiles the callback Web Service and packages it in the same EAR file as the client Web Service.
A Web Service and the client application that invokes it may communicate multiple times to complete a single task. Also, multiple client applications might communicate with the same Web Service at the same time. Conversations provide a straightforward way to keep track of data between calls and to ensure that the Web Service always responds to the correct client.
Conversations meet two challenges inherent in persisting data across multiple communications:
WebLogic Server manages this unique ID and state by creating a conversation context each time a client application initiates a new conversation. The Web Service then uses the context to correlate calls to and from the service and to persist its state-related data.
Conversations between a client application and a Web Service have three distinct phases:
Conversations typically occur between two WebLogic Web Services: one is marked conversational and defines the start, continue, and finish operations and the other Web Service uses the @ServiceClient
annotation to specify that it is a client of the conversational Web Service. You can also invoke a conversational Web Service from a stand-alone Java client, although there are restrictions.
As with other WebLogic Web Service features, you use JWS annotations to specify that a Web Service is conversational.
WARNING: | The client Web Service that invokes a conversational Web Service is not required to also be conversational. However, if the client is not conversational, there is a danger of multiple instances of this client accessing the same conversational Web Service stub and possibly corrupting the saved conversational state. If you believe this might true in your case, then specify that the client Web Service also be conversational. In this case you cannot use a stand-alone Java client, because there is no way to mark it as conversational using the WebLogic APIs. |
Caution: | A conversational Web Service on its own does not guarantee message delivery or that the messages are delivered in order, exactly once. If you require this kind of message delivery guarantee, you must also specify that the Web Service be reliable. See Using Web Service Reliable Messaging and Using the Asynchronous Features Together. |
The following procedure describes how to create a conversational Web Service, as well as a client Web Service and stand-alone Java client application, both of which initiate and conduct a conversation. The procedure shows how to create the JWS files that implement the two Web Services from scratch. If you want to update existing JWS files, you can also use this procedure as a guide.
It is assumed that you have set up an Ant-based development environment and that you have a working build.xml
file to which you can add targets for running the jwsc
Ant task and deploying the generated conversational Web Service. It is further assumed that you have a similar setup for the WebLogic Server instance that hosts the client Web Service that initiates the conversation. For more information, see Common Web Services Use Cases and Examples, Iterative Development of WebLogic Web Services, and Programming the JWS File..
See Programming Guidelines for the Conversational JWS File.
build.xml
file to include a call to the jwsc
Ant task to compile the conversational JWS file into a Web Service.See Running the jwsc WebLogic Web Services Ant Task.
prompt> ant build-mainService
See Deploying and Undeploying WebLogic Web Services.
See Programming Guidelines for the JWS File That Invokes a Conversational Web Service.
build.xml
file that builds the client Web Service.See Updating the build.xml File for a Client of a Conversational Web Service.
prompt> ant build-clientService
The following example shows a simple JWS file that implements a conversational Web Service; see the explanation after the example for coding guidelines that correspond to the Java code in bold.
package examples.webservices.conversation;
import java.io.Serializable;
import weblogic.jws.WLHttpTransport;import weblogic.jws.Conversation;
import weblogic.jws.Conversational;
import weblogic.jws.Context;
import weblogic.wsee.jws.JwsContext;
import weblogic.wsee.jws.ServiceHandle;
import javax.jws.WebService;
import javax.jws.WebMethod;
@Conversational(maxIdleTime="10 minutes",
maxAge="1 day",
runAsStartUser=false,
singlePrincipal=false )
@WebService(name="ConversationalPortType",
serviceName="ConversationalService",
targetNamespace="http://examples.org/")
@WLHttpTransport(contextPath="conv",
serviceUri="ConversationalService",
portName="ConversationalServicePort")
/**
* Conversational Web Service.
*/
public class ConversationalServiceImpl implements Serializable {
@Context
private JwsContext ctx;
public String status = "undefined";
@WebMethod@Conversation (Conversation.Phase.START)
public String start() {
ServiceHandle handle = ctx.getService();
String convID = handle.getConversationID();
status = "start";
return "Starting conversation, with ID " + convID + " and status equal to " + status;
}
@WebMethod@Conversation (Conversation.Phase.CONTINUE)
public String middle(String message) {
status = "middle";
return "Middle of conversation; the message is: " + message + " and status is " + status;
}
@WebMethod@Conversation (Conversation.Phase.FINISH)
public String finish(String message ) {
status = "finish";
return "End of conversation; the message is: " + message + " and status is " + status;
}
}
Follow these guidelines when programming the JWS file that implements a conversational Web Service. Code snippets of the guidelines are shown in bold in the preceding example.
java.io.Serializable
, so you must first import the class into your JWS file:import java.io.Serializable;
import weblogic.jws.Conversation;
import weblogic.jws.Conversational;
@Context
annotation and context APIs:import weblogic.jws.Context;
import weblogic.wsee.jws.JwsContext;
import weblogic.wsee.jws.ServiceHandle;
See Accessing Runtime Information about a Web Service Using the JwsContext for more information about the runtime Web Service context.
@Conversational
annotation to specify that the Web Service is conversational. Although this annotation is optional (assuming you are specifying the @Conversation
method-level annotation), it is a best practice to always use it in your JWS file to clearly specify that your Web Service is conversational.
Specify any of the following optional attributes: maxIdleTime
is the maximum amount of time that the Web Service can be idle before WebLogic Server finishes the conversation; maxAge
is the maximum age of the conversation; runAsStartUser
indicates whether the continue and finish phases of an existing conversation are run as the user who started the conversation; and singlePrincipal
indicates whether users other than the one who started a conversation are allowed to execute the continue and finish phases of the conversation.
@Conversational(maxIdleTime="10 minutes",
maxAge="1 day",
runAsStartUser=false,
singlePrincipal=false )
If a JWS file includes the @Conversational
annotation, all operations of the Web Service are conversational. The default phase of an operation, if it does not have an explicit @Conversation
annotation, is continue. However, because a conversational Web Service is required to include at least one start and one finish operation, you must use the method-level @Conversation
annotation to specify which methods implement these operations.
See weblogic.jws.Conversational for additional information and default values for the attributes.
java.io.Serializable
:public class ConversationalServiceImpl implements Serializable {
weblogic.wsee.jws.JwsContext
, with the field-level @Context
JWS annotation:@Context
private JwsContext ctx;
@Conversation
annotation to specify the methods that implement the start, continue, and finish phases of your conversation. A conversation is required to have at least one start and one finish operation; the continue operation is optional. Use the following parameters to the annotation to specify the phase: Conversation.Phase.START
, Conversation.Phase.CONTINUE
, or Conversation.Phase.FINISH
. The following example shows how to specify the start operation:@WebMethod
@Conversation (Conversation.Phase.START)
public String start() {...
If you mark just one method of the JWS file with the @Conversation
annotation, then the entire Web Service becomes conversational and each operation is considered part of the conversation; this is true even if you have not used the optional class-level @Conversational
annotation in your JWS file. Any methods not explicitly annotated with @Conversation
are, by default, continue operations. This means that, for example, if a client application invokes one of these continue methods without having previously invoked a start operation, the Web Service returns a runtime error.
Finally, if you plan to invoke the conversational Web Service from a stand-alone Java client, the start operation is required to be request-response, or in other words, it cannot be annotated with the @Oneway
JWS annotation. The operation can return void
. If you are going to invoke the Web Service only from client applications that run in WebLogic Server, then this requirement does not apply.
See weblogic.jws.Conversation for additional information.
JwsContext
instance to get runtime information about the Web Service.For example, the following code in the start operation gets the ID that WebLogic Server assigns to the new conversation:
ServiceHandle handle = ctx.getService();
String convID = handle.getConversationID();
See Accessing Runtime Information about a Web Service Using the JwsContext for detailed information on using the context-related APIs.
The following example shows a simple JWS file for a Web Service that invokes the conversational Web Service described in Programming Guidelines for the Conversational JWS File; see the explanation after the example for coding guidelines that correspond to the Java code in bold.
package examples.webservices.conversation;
import weblogic.jws.WLHttpTransport;import weblogic.jws.ServiceClient;
import weblogic.wsee.conversation.ConversationUtils;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.xml.rpc.Stub;
import examples.webservices.conversation.ConversationalPortType;
import java.rmi.RemoteException;
@WebService(name="ConversationalClientPortType",
serviceName="ConversationalClientService",
targetNamespace="http://examples.org/")
@WLHttpTransport(contextPath="convClient",
serviceUri="ConversationalClient",
portName="ConversationalClientPort")
/**
* client that has a conversation with the ConversationalService.
*/
public class ConversationalClientImpl {
@ServiceClient(
wsdlLocation="http://localhost:7001/conv/ConversationalService?WSDL",
serviceName="ConversationalService",
portName="ConversationalServicePort")
private ConversationalPortType port;
@WebMethod
public void runConversation(String message) {
try {
// Invoke start operationString result = port.start();
System.out.println("start method executed.");
System.out.println("The message is: " + result);
// Invoke continue operationresult = port.middle(message );
System.out.println("middle method executed.");
System.out.println("The message is: " + result);
// Invoke finish operationresult = port.finish(message );
System.out.println("finish method executed.");
System.out.println("The message is: " + result);ConversationUtils.renewStub((Stub)port);
}
catch (RemoteException e) {
e.printStackTrace();
}
}
}
Follow these guidelines when programming the JWS file that invokes a conversational Web Service; code snippets of the guidelines are shown in bold in the preceding example:
@ServiceClient
JWS annotation:import weblogic.jws.ServiceClient;
import weblogic.wsee.conversation.ConversationUtils;
jwsc
Ant task. The stub package is specified by the packageName
attribute of the <clientgen>
child element of <jws>
, and the name of the stub is determined by the WSDL of the invoked Web Service.import examples.webservices.conversation.ConversationalPortType;
@ServiceClient
JWS annotation to specify the WSDL, name, and port of the conversational Web Service you want to invoke. You specify this annotation at the field-level on a private variable, whose data type is the JAX-RPC port type of the Web Service you are invoking. @ServiceClient(
wsdlLocation="http://localhost:7001/conv/ConversationalService?WSDL",
serviceName="ConversationalService",
portName="ConversationalServicePort")
private ConversationalPortType port;
@ServiceClient
annotation, invoke the start operation of the conversational Web Service to start the conversation. You can invoke the start method from any location in the JWS file (constructor, method, and so on):
String result = port.start();
result = port.middle(message );
result = port.finish(message );
renewStub()
method of the weblogic.wsee.conversation.ConversationUtils
utility class:ConversationUtils.renewStub((Stub)port);
WARNING: | The client Web Service that invokes a conversational Web Service is not required to also be conversational. However, if the client is not conversational, there is a danger of multiple instances of this client accessing the same conversational Web Service stub and possibly corrupting the saved conversational state. If you believe this might true in your case, then specify that the client Web Service also be conversational. |
WebLogic Server provides a utility class for use with the conversation feature. Use this class to perform common tasks such as getting and setting the conversation ID and setting configuration options. Some of these tasks are performed in the conversational Web Service, some are performed in the client that invokes the conversational Web Service. See Programming Guidelines for the JWS File That Invokes a Conversational Web Service for an example of using this class.
See weblogic.wsee.conversation.ConversationUtils for details.
You update a build.xml
file to generate the JWS file that invokes a conversational Web Service by adding taskdefs
and a build-clientService
target that looks something like the following example. See the description after the example for details.
<taskdef name="jwsc"
classname="weblogic.wsee.tools.anttasks.JwscTask" />
<target name="build-clientService">
<jwsc
enableAsyncService="true"
srcdir="src"
destdir="${clientService-ear-dir}" >
<jws file="examples/webservices/conversation/ConversationalClientImpl.java" ><clientgen
wsdl="http://${wls.hostname}:${wls.port}/conv/ConversationalService?WSDL"
packageName="examples.webservices.conversation"/>
</jws>
</jwsc>
</target>
Use the taskdef
Ant task to define the full classname of the jwsc
Ant tasks.
Update the jwsc
Ant task that compiles the client Web Service to include a <clientgen>
child element of the <jws>
element so as to generate and compile the JAX-RPC stubs for the deployed ConversationalService
Web Service. The jwsc
Ant task automatically packages them in the generated WAR file so that the client Web Service can immediately access the stubs. You do this because the ConversationalClientImpl
JWS file imports and uses one of the generated classes.
The following example shows a simple stand-alone Java client that invokes the conversational Web Service described in Programming Guidelines for the Conversational JWS File. See the explanation after the example for coding guidelines that correspond to the Java code in bold.
package examples.webservices.conv_standalone.client;
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.Stub;
import weblogic.wsee.jaxrpc.WLStub;
/**
* stand-alone client that invokes and converses with ConversationlService.
*/
public class Main {
public static void main(String[] args)
throws ServiceException, RemoteException{
ConversationalService service = new ConversationalService_Impl(args[0] + "?WSDL");
ConversationalPortType port = service.getConversationalServicePort();
// Set property on stub to specify that client is invoking a Web Service
// that uses advanced features; this property is automatically set if
// the client runs in a WebLogic Server instance.
Stub stub = (Stub)port;
stub._setProperty(WLStub.COMPLEX, "true");
// Invoke start operation to begin the conversationString result = port.start();
System.out.println("start method executed.");
System.out.println("The message is: " + result);
// Invoke continue operationresult = port.middle("middle" );
System.out.println("middle method executed.");
System.out.println("The message is: " + result);
// Invoke finish operationresult = port.finish("finish" );
System.out.println("finish method executed.");
System.out.println("The message is: " + result);
}
}
Follow these guidelines when programming the stand-alone Java client that invokes a conversational Web Service. Code snippets of the guidelines are shown in bold in the preceding example.
weblogic.wsee.jaxrpc.WLStub
class:import weblogic.wsee.jaxrpc.WLStub;
WLStub.Complex
property on the JAX-RPC stub of the ConversationalService
using the _setProperty
method:Stub stub = (Stub)port;
stub._setProperty(WLStub.COMPLEX, "true");
This property specifies to the Web Services runtime that the client is going to invoke an advanced Web Service, in this case a conversational one. This property is automatically set when invoking a conversational Web Service from another WebLogic Web Service.
String result = port.start();
result = port.middle(message );
result = port.finish(message );
WebLogic Server supports production redeployment, which means that you can deploy a new version of an updated conversational WebLogic Web Service alongside an older version of the same Web Service.
WebLogic Server automatically manages client connections so that only new client requests are directed to the new version. Clients already connected to the Web Service during the redeployment continue to use the older version of the service until they complete their work, at which point WebLogic Server automatically retires the older Web Service. If the client is connected to a conversational Web Service, its work is considered complete when the existing conversation is explicitly ended by the client or because of a timeout.
For additional information about production redployment and Web Service clients, see Client Considerations When Redeploying a Web Service .
When a buffered operation is invoked by a client, the method operation goes on a JMS queue and WebLogic Server deals with it asynchronously. As with Web Service reliable messaging, if WebLogic Server goes down while the method invocation is still in the queue, it will be dealt with as soon as WebLogic Server is restarted. When a client invokes the buffered Web Service, the client does not wait for a response from the invoke, and the execution of the client can continue.
The following procedure describes how to create a buffered Web Service and a client Web Service that invokes an operation of the buffered Web Service. The procedure shows how to create the JWS files that implement the two Web Services from scratch. If you want to update existing JWS files, use this procedure as a guide. The procedure also shows how to configure the WebLogic Server instance that hosts the buffered Web Service.
Note: | Unless you are also using the asynchronous request-response feature, you do not need to invoke a buffered Web Service from another Web Service, you can also invoke it from a stand-alone Java application. |
It is assumed that you have set up an Ant-based development environment and that you have a working build.xml
file to which you can add targets for running the jwsc
Ant task and deploying the generated buffered Web Service. It is further assumed that you have a similar setup for the WebLogic Server instance that hosts the client Web Service that invokes the buffered Web Service. For more information, see:
See Configuring the Host WebLogic Server Instance for the Buffered Web Service.
See Programming Guidelines for the Buffered JWS File.
build.xml
file to include a call to the jwsc
Ant task to compile the JWS file into a buffered Web Service; for example:<jwsc
srcdir="src"
destdir="${service-ear-dir}" >
<jws
file="examples/webservices/async_buffered/AsyncBufferedImpl.java"
/>
</jwsc>
See Running the jwsc WebLogic Web Services Ant Task for general information about using the jwsc
task.
prompt> ant build-mainService deploy-mainService
See Programming the JWS File That Invokes the Buffered Web Service.
build.xml
file that builds the client Web Service.See Updating the build.xml File for a Client of the Buffered Web Service.
prompt> ant build-clientService deploy-clientService
Configuring the WebLogic Server instance on which the buffered Web Service is deployed involves configuring JMS resources, such as JMS servers and modules, that are used internally by the Web Services runtime.
You can either configure these resources yourself, or you can use the Configuration Wizard to extend the WebLogic Server domain using a Web Services-specific extension template. Using the Configuration Wizard greatly simplifies the required configuration steps; for details, see Configuring Your Domain For Web Services Features.
If, however, you prefer to configure the resources yourself, use the following high-level procedure which lists the tasks and then points to the Administration Console Online Help for details on performing the tasks.
See Invoking the Administration Console for instructions on the URL that invokes the Administration Console.
See Create JMS servers.
If you want the buffered Web Service to use the default Web Services queue, set the JNDI name of the JMS queue to weblogic.wsee.DefaultQueue
. Otherwise, if you use a different JNDI name, be sure to use the @BufferQueue
annotation in the JWS file to specify this JNDI name to the reliable Web Service. See Programming Guidelines for the Buffered JWS File.
If you are using the buffered Web Service feature in a cluster, you must still create a local queue rather than a distributed queue. In addition, you must explicitly target this queue to each server in the cluster.
See Create JMS modules and Create queues.
The following example shows a simple JWS file that implements a buffered Web Service; see the explanation after the example for coding guidelines that correspond to the Java code in bold.
package examples.webservices.buffered;
import javax.jws.WebMethod;
import javax.jws.WebService;import javax.jws.Oneway;
import weblogic.jws.WLHttpTransport;import weblogic.jws.MessageBuffer;
import weblogic.jws.BufferQueue;
@WebService(name="BufferedPortType",
serviceName="BufferedService",
targetNamespace="http://example.org")
@WLHttpTransport(contextPath="buffered",
serviceUri="BufferedService",
portName="BufferedPort")
// Annotation to specify a specific JMS queue rather than the default
@BufferQueue(name="my.jms.queue")
/**
* Simple buffered Web Service.
*/
public class BufferedImpl {
@WebMethod()@MessageBuffer(retryCount=10, retryDelay="10 seconds")
@Oneway()
public void sayHelloNoReturn(String message) {
System.out.println("sayHelloNoReturn: " + message);
}
}
Follow these guidelines when programming the JWS file that implements a buffered Web Service. Code snippets of the guidelines are shown in bold in the preceding example.
import javax.jws.Oneway;
import weblogic.jws.MessageBuffer;
import weblogic.jws.BufferQueue;
See the following bullets for guidelines on which JWS annotations are required.
@BufferQueue
JWS annotation to specify the JNDI name of the JMS queue used internally by WebLogic Server when it processes a buffered invoke; for example:
@BufferQueue(name="my.jms.queue")
If you do not specify this JWS annotation, then WebLogic Server uses the default Web Services JMS queue (weblogic.wsee.DefaultQueue
).
You must create both the default JMS queue and any queues specified with this annotation before you can successfully invoke a buffered operation. See Configuring the Host WebLogic Server Instance for the Buffered Web Service for details.
@MessageBuffer
JWS annotation to specify the operations of the Web Service that are buffered. The annotation has two optional attributes: retryCount
: The number of times WebLogic Server should attempt to deliver the message from the JMS queue to the Web Service implementation (default 3).retryDelay
: The amount of time that the server should wait in between retries (default 5 minutes).@MessageBuffer(retryCount=10, retryDelay="10 seconds")
You can use this annotation at the class-level to specify that all operations are buffered, or at the method-level to choose which operations are buffered.
@Oneway
annotation to specify that the method is one-way. This means that the method cannot return a value, but rather, must explicitly return void
. For example:@Oneway()
public void sayHelloNoReturn(String message) {
Conversely, if the method is not annotated with the @Oneway
annotation, then you must invoke it using the asynchronous request-response feature. If you are unsure how the operation is going to be invoked, consider creating two flavors of the operation: synchronous and asynchronous.
See Invoking a Web Service Using Asynchronous Request-Response and Using the Asynchronous Features Together.
You can invoke a buffered Web Service from both a stand-alone Java application (if not using asynchronous request-response) and from another Web Service. Unlike other WebLogic Web Services asynchronous features, however, you do not use the @ServiceClient
JWS annotation in the client Web Service, but rather, you invoke the service as you would any other. For details, see Invoking a Web Service from Another Web Service.
The following sample JWS file shows how to invoke the sayHelloNoReturn
operation of the BufferedService
Web Service:
package examples.webservices.buffered;
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;
import javax.jws.WebService;
import javax.jws.WebMethod;
import weblogic.jws.WLHttpTransport;
import examples.webservices.buffered.BufferedPortType;
import examples.webservices.buffered.BufferedService_Impl;
import examples.webservices.buffered.BufferedService;
@WebService(name="BufferedClientPortType",
serviceName="BufferedClientService",
targetNamespace="http://examples.org")
@WLHttpTransport(contextPath="bufferedClient",
serviceUri="BufferedClientService",
portName="BufferedClientPort")
public class BufferedClientImpl {
@WebMethod()
public String callBufferedService(String input, String serviceUrl)
throws RemoteException {
try {
BufferedService service = new BufferedService_Impl(serviceUrl + "?WSDL");
BufferedPortType port = service.getBufferedPort();
// Invoke the sayHelloNoReturn() operation of BufferedService
port.sayHelloNoReturn(input);
return "Invoke went okay!";
} catch (ServiceException se) {
System.out.println("ServiceExcpetion thrown");
throw new RuntimeException(se);
}
}
}
To update a build.xml
file to generate the JWS file that invokes a buffered Web Service operation, add taskdefs
and a build-clientService
targets that look something like the following example. See the description after the example for details.
<taskdef name="jwsc"
classname="weblogic.wsee.tools.anttasks.JwscTask" />
<target name="build-clientService">
<jwsc
enableAsyncService="true"
srcdir="src"
destdir="${clientService-ear-dir}" >
<jws file="examples/webservices/buffered/BufferedClientImpl.java">
<clientgen
wsdl="http://${wls.hostname}:${wls.port}/buffered/BufferedService?WSDL"
packageName="examples.webservices.buffered"/>
</jws>
</jwsc>
</target>
Use the taskdef
Ant task to define the full classname of the jwsc
Ant tasks.
Update the jwsc
Ant task that compiles the client Web Service to include a <clientgen>
child element of the <jws>
element so as to generate and compile the JAX-RPC stubs for the deployed BufferedService
Web Service. The jwsc
Ant task automatically packages them in the generated WAR file so that the client Web Service can immediately access the stubs. You do this because the BufferedClientImpl
JWS file imports and uses one of the generated classes.
The preceding sections describe how to use the WebLogic Web Service asynchronous features (Web Service reliable messaging, conversations, asynchronous request-response, and buffering) on their own. Typically, however, Web Services use the features together; see Example of a JWS File That Implements a Reliable Conversational Web Service and Example of Client Web Service That Asynchronously Invokes a Reliable Conversational Web Service for examples.
When used together, some restrictions described in the individual feature sections do not apply, and sometimes additional restrictions apply.
When you create the JMS queue on the source WebLogic Server instance, you are required to specify a JNDI name of weblogic.wsee.DefaultQueue
; you can name the queue anything you want. You must also ensure that you specify that this JMS queue is local, typically by setting the local JNDI name.
@Oneway
annotation.AsyncPreCallContext
or AsyncPostCallContext
), then the property must implement java.io.Serializable
.@ServiceClient
JWS annotation in the client Web Service that invokes the buffered Web Service operation. WLStub.CONVERSATIONAL_METHOD_BLOCK_TIMEOUT
on the stub of the client Web Service, the property is ignored because the client does not block.@Oneway
annotation.WebServiceA
is conversational, and it invokes WebServiceB
using asynchronous request-response. Because WebServiceA
is conversational the asynchronous responses from WebServiceB
also participates in the same conversation.The following sample JWS file implements a Web Service that is both reliable and conversational:
package examples.webservices.async_mega;
import java.io.Serializable;
import weblogic.jws.WLHttpTransport;
import weblogic.jws.Conversation;
import weblogic.jws.Policy;
import javax.jws.WebService;
import javax.jws.WebMethod;
@WebService(name="AsyncMegaPortType",
serviceName="AsyncMegaService",
targetNamespace="http://examples.org/")
@Policy(uri="AsyncReliableConversationPolicy.xml",
attachToWsdl=true)
@WLHttpTransport(contextPath="asyncMega",
serviceUri="AsyncMegaService",
portName="AsyncMegaServicePort")
/**
* Web Service that is both reliable and conversational.
*/
public class AsyncMegaServiceImpl implements Serializable {
@WebMethod
@Conversation (Conversation.Phase.START)
public String start() {
return "Starting conversation";
}
@WebMethod
@Conversation (Conversation.Phase.CONTINUE)
public String middle(String message) {
return "Middle of conversation; the message is: " + message;
}
@WebMethod
@Conversation (Conversation.Phase.FINISH)
public String finish(String message ) {
return "End of conversation; the message is: " + message;
}
}
The following JWS file shows how to implement a client Web Service that reliably invokes the various conversational methods of the Web Service described in Example of a JWS File That Implements a Reliable Conversational Web Service; the client JWS file uses the asynchronous request-response feature as well.
package examples.webservices.async_mega;
import weblogic.jws.WLHttpTransport;
import weblogic.jws.ServiceClient;
import weblogic.jws.AsyncResponse;
import weblogic.jws.AsyncFailure;
import javax.jws.WebService;
import javax.jws.WebMethod;
import weblogic.wsee.async.AsyncPreCallContext;
import weblogic.wsee.async.AsyncCallContextFactory;
import weblogic.wsee.async.AsyncPostCallContext;
import examples.webservices.async_mega.AsyncMegaPortType;
import examples.webservices.async_mega.AsyncMegaService;
import examples.webservices.async_mega.AsyncMegaService_Impl;
import java.rmi.RemoteException;
@WebService(name="AsyncMegaClientPortType",
serviceName="AsyncMegaClientService",
targetNamespace="http://examples.org/")
@WLHttpTransport(contextPath="asyncMegaClient",
serviceUri="AsyncMegaClient",
portName="AsyncMegaClientServicePort")
/**
* Client Web Service that has a conversation with the AsyncMegaService
* reliably and asynchronously.
*/
public class AsyncMegaClientImpl {
@ServiceClient(
wsdlLocation="http://localhost:7001/asyncMega/AsyncMegaService?WSDL",
serviceName="AsyncMegaService",
portName="AsyncMegaServicePort")
private AsyncMegaPortType port;
@WebMethod
public void runAsyncReliableConversation(String message) {
AsyncPreCallContext apc = AsyncCallContextFactory.getAsyncPreCallContext();
apc.setProperty("message", message);
try {
port.startAsync(apc);
System.out.println("start method executed.");
port.middleAsync(apc, message );
System.out.println("middle method executed.");
port.finishAsync(apc, message );
System.out.println("finish method executed.");
}
catch (RemoteException e) {
e.printStackTrace();
}
}
@AsyncResponse(target="port", operation="start")
public void onStartAsyncResponse(AsyncPostCallContext apc, String message) {
System.out.println("-------------------");
System.out.println("Got message " + message );
System.out.println("-------------------");
}
@AsyncResponse(target="port", operation="middle")
public void onMiddleAsyncResponse(AsyncPostCallContext apc, String message) {
System.out.println("-------------------");
System.out.println("Got message " + message );
System.out.println("-------------------");
}
@AsyncResponse(target="port", operation="finish")
public void onFinishAsyncResponse(AsyncPostCallContext apc, String message) {
System.out.println("-------------------");
System.out.println("Got message " + message );
System.out.println("-------------------");
}
@AsyncFailure(target="port", operation="start")
public void onStartAsyncFailure(AsyncPostCallContext apc, Throwable e) {
System.out.println("-------------------");
e.printStackTrace();
System.out.println("-------------------");
}
@AsyncFailure(target="port", operation="middle")
public void onMiddleAsyncFailure(AsyncPostCallContext apc, Throwable e) {
System.out.println("-------------------");
e.printStackTrace();
System.out.println("-------------------");
}
@AsyncFailure(target="port", operation="finish")
public void onFinishAsyncFailure(AsyncPostCallContext apc, Throwable e) {
System.out.println("-------------------");
e.printStackTrace();
System.out.println("-------------------");
}
}
Client applications that invoke reliable Web Services or use the asynchronous request-response feature might not invoke the operation directly, but rather, use a proxy server. Reasons for using a proxy include the presence of a firewall or the deployment of the invoked Web Service to a cluster.
In this case, the WebLogic Server instance that hosts the invoked Web Service must be configured with the address and port of the proxy server. If your Web Service is deployed to a cluster, you must configure every server in the cluster.
weblogic-wsee-proxy-channel-
XXX
, where XXX
refers to the protocol. For example, to create a network channel for HTTPS, call it weblogic-wsee-proxy-channel-https
. See Configure Custom Network Channels for general information about creating a network channel.