The following sections describe how to use callbacks to notify clients of events:
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 a 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:
Callback interface: Java interface file that defines the callback methods. You do not explicitly implement this file yourself; rather, the 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()
.
JWS file that implements the target Web service: The target Web service includes one or more standard operations that invoke a method defined in the callback interface; this method in turn sends a message back to the client Web service that originally invoked the operation of the target Web service.
In the example, this Web service is called TargetService
and it defines a single standard method called targetOperation()
.
JWS file that implements the client Web service: The client Web service invokes an operation of the target Web service. This Web service includes one or more methods that specify what the client should do when it receives a callback message back from the target Web service via a callback method.
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:
The 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.
The implementation of the 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.
The 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 Getting Started With JAX-RPC Web Services for Oracle WebLogic Server.
Table 7-1 Steps to Program Callbacks
# |
Step | Description |
---|---|---|
1 |
Create a new JWS file, or update an existing one, that implements the target Web service. |
Use your favorite IDE or text editor. 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. |
2 |
Update your |
See "Running the jwsc WebLogic Web Services Ant Task" in Getting Started With JAX-RPC Web Services for Oracle WebLogic Server. |
3 |
Run the Ant target to build the target Web service. |
For example: prompt> ant build-mainService |
4 |
Deploy the target Web service as usual. |
See "Deploying and Undeploying WebLogic Web Services" in Getting Started With JAX-RPC Web Services for Oracle WebLogic Server. |
5 |
Create a new JWS file, or update an existing one, that implements the client Web service. |
It is assumed that the client Web service is deployed to a different WebLogic Server instance from the one that hosts the target Web service. See Programming Guidelines for the Callback Client Web Service. |
6 |
Create the callback JWS interface that implements the callback Web service. |
|
7 |
Update the |
The |
8 |
Run the Ant target to build the client and callback Web services. |
For example: prompt> ant build-clientService |
9 |
Deploy the client Web service as usual. |
See "Deploying and Undeploying WebLogic Web Services" in Getting Started With JAX-RPC Web Services for Oracle WebLogic Server. |
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 the required JWS annotations:
import weblogic.jws.Callback;
Use the @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;
In a method that implements an operation of the 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" in WebLogic Web Services Reference for Oracle WebLogic Server for additional information about the WebLogic-specific 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 the required JWS annotations:
import weblogic.jws.ServiceClient; import weblogic.jws.CallbackMethod;
Optionally import the security-related annotations if you want to specify the roles that are allowed to invoke the callback methods:
import weblogic.jws.security.CallbackRolesAllowed; import weblogic.jws.security.SecurityRole;
Import the JAX-RPC stub of the port type of the target Web service you want to invoke. The actual stub itself will be created later by the 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;
In the body of the JWS file, use the @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.
Using the variable you annotated with the @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);
Create a method that will handle the callback message received from the callback service. You can name this method anything you want. However, its signature should exactly match the signature of the corresponding method in the callback interface.
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" in WebLogic Web Services Reference for Oracle WebLogic Server for additional information about the WebLogic-specific 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:
You cannot use any WebLogic-specific JWS annotations other than @weblogic.jws.CallbackService
.
You can use all standard JWS annotations except for the following:
javax.jws.HandlerChain
javax.jws.soap.SOAPMessageHandler
javax.jws.soap.SOAPMessageHandlers
You can use all supported data types as parameters or return values except 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 @Oneway public 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 the required JWS annotation:
import weblogic.jws.CallbackService;
Annotate the interface declaration with the @CallbackService
annotation to specify that the JWS file implements a callback service:
@CallbackService public interface CallbackInterface {
Create a method that the target Web service explicitly invokes; this is the method that automatically sends a message back to the client service that originally invoked the target Web service. Because this is a Java interface file, you do not provide an implementation of this method. Rather, the WebLogic Web services runtime generates an implementation of the method via the 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" in WebLogic Web Services Reference for Oracle WebLogic Server for additional information about the WebLogic-specific 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.