26 Using Callbacks
This chapter includes the following sections:
Overview of Callbacks
A callback is a contract between a client and service that allows the service to invoke operations on a client-provided endpoint during the invocation of a service method for the purpose of querying the client for additional data, allowing the client to inject behavior, or notifying the client of progress. The service advertises the requirements for the callback using a WSDL that defines the callback port type and the client informs the service of the callback endpoint address using WS-Addressing.
Example Callback Implementation
The example callback implementation described in this section consists of the following three Java files:
-
JWS file that implements the callback web service: The callback web service defines the callback methods. The implementation simply passes information back to the target web service that, in turn, passes the information back to the client web service.
In the example in this section, the callback web service is called
CallbackService
. The web service defines a single callback method calledcallback()
. -
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 web service and sends the 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 calledtargetOperation()
. -
JWS file that implements the client web service: The client web service invokes an operation of the target web service. Often, this web service will include 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
CallerService
. The method that invokesTargetService
in the standard way is calledcall()
.
The following shows the flow of messages for the example callback implementation.
Figure 26-1 Example Callback Implementation
Description of "Figure 26-1 Example Callback Implementation"
-
The
call()
method of theCallerService
web service, running in one WebLogic Server instance, explicitly invokes thetargetOperation()
method of theTargetService
and passes a web service endpoint to theCallbackService
. Typically, theTargetService
service is running in a separate WebLogic Server instance. -
The implementation of the
TargetService.targetOperation()
method explicitly invokes thecallback()
method of theCallbackService
, which implements the callback service, using the web service endpoint that is passed in fromCallerService
when the method is called. -
The
CallbackService.callback()
method sends information back to theTargetService
web service. -
The
TargetService.targetOperation()
method, in turn, sends the information back to theCallerService
service, completing the callback sequence.
Steps to Program Callbacks
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 web service. 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 Programming the JWS File.
Table 26-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 web service. However, the step that describes how to program the callback web service 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 |
|
3 |
Run the Ant target to build the target web service. |
For example: prompt> ant build-target |
4 |
Deploy the target web service as usual. |
|
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 JWS file that implements the callback web service. |
|
7 |
Update the |
The <clientgen type="JAXWS" wsdl="${awsdl}" packageName="jaxws.callback.client.add"/> <clientgen type="JAXWS" wsdl="${twsdl}" packageName="jaxws.callback.client.target"/> <FileSet dir="." > <include name="CallbackWS.java" /> </FileSet> |
8 |
Run the Ant target to build the client and callback web services. |
For example: prompt> ant build-caller |
9 |
Deploy the client web service as usual. |
Programming Guidelines for Target Web Service
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 javax.jws.WebService; import javax.xml.ws.BindingType; import javax.xml.ws.wsaddressing.W3CEndpointReference; import examples.webservices.callback.callbackservice.*; @WebService( portName="TargetPort", serviceName="TargetService", targetNamespace="http://example.oracle.com", endpointInterface= "examples.webservices.callback.target.TargetPortType", wsdlLocation="/wsdls/Target.wsdl") @BindingType(value="http://schemas.xmlsoap.org/wsdl/soap/http") public class TargetImpl { public String targetOperation(String s, W3CEndpointReference callback) { CallbackService aservice = new CallbackService(); CallbackPortType aport = aservice.getPort(callback, CallbackPortType.class); String result = aport.callback(s); return result + " processed by target"; } }
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 packages required to pass the callback service endpoint and access the
CallbackService
stub implementation.import javax.xml.ws.wsaddressing.W3CEndpointReference; import examples.webservices.callback.callbackservice.*;
-
Create an instance of the
CallbackService
implementation using the stub implementation and get a port by passing theCallbackService
service endpoint, which is passed by the calling application (CallerService
).CallbackService aservice = new CallbackService(); CallbackPortType aport = aservice.getPort(callback, CallbackPortType.class);
-
Invoke the callback operation of
CallbackService
using the port you instantiated:String result = aport.callback(s);
-
Return the result to the
CallerService
service.return result + " processed by target";
Programming Guidelines for the Callback Client Web Service
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 javax.annotation.Resource; import javax.jws.WebMethod; import javax.jws.WebService; import javax.xml.ws.BindingType; import javax.xml.ws.Endpoint; import javax.xml.ws.WebServiceContext; import javax.xml.ws.WebServiceException; import javax.xml.ws.WebServiceRef; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.wsaddressing.W3CEndpointReference; import examples.webservices.callback.target.*; @WebService( portName="CallerPort", serviceName="CallerService", targetNamespace="http://example.oracle.com") @BindingType(value="http://schemas.xmlsoap.org/wsdl/soap/http") public class CallerImpl { @Resource private WebServiceContext context; @WebServiceRef() private TargetService target; @WebMethod() public String call(String s) { Object sc = context.getMessageContext().get(MessageContext.SERVLET_CONTEXT); Endpoint callbackImpl = Endpoint.create(new CallbackWS()); callbackImpl.publish(sc); TargetPortType tPort = target.getTargetPort(); String result = tPort.targetOperation(s, callbackImpl.getEndpointReference(W3CEndpointReference.class)); callbackImpl.stop(); return result; } }
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 packages required to access the servlet context, publish the web service endpoint, and access the
TargetService
stub implementation.import javax.xml.ws.Endpoint; import javax.xml.ws.WebServiceContext; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.wsaddressing.W3CEndpointReference; import examples.webservices.callback.target.*;
-
Get the servlet context using the
WebServiceContext
andMessageContext
. You will use the servlet context when publishing the web service endpoint, later.@Resource private WebServiceContext context; . . . Object sc context.getMessageContext().get(MessageContext.SERVLET_CONTEXT);
For more information about accessing runtime information using
WebServiceContext
andMessageContext
, see Accessing Runtime Information About a Web Service. -
Create a web service endpoint to the
CallbackService
implementation and publish that endpoint to accept incoming requests.Endpoint callbackImpl = Endpoint.create(new CallbackWS()); callbackImpl.publish(sc);
For more information about web service publishing, see Publishing a Web Service Endpoint.
-
Access an instance of the
TargetService
stub implementation and invoke thetargetOperation
operation ofTargetService
using the port you instantiated. You pass theCallbackService
service endpoint as ajavax.xml.ws.wsaddressing.W3CEndpointReference
data type:Note:
Ensure that the callback web service is deployed during the range of time that callbacks may arrive.
@WebServiceRef() private TargetService target; . . . TargetPortType tPort = target.getTargetPort(); String result = tPort.targetOperation(s, callbackImpl.getEndpointReference(W3CEndpointReference.class));
-
Stop publishing the endpoint:
callbackImpl.stop();
Programming Guidelines for the Callback Web Service
The following example shows a simple JWS file for a callback web service. The callback
operation is shown in bold.
package examples.webservices.callback;
import javax.jws.WebService;
import javax.xml.ws.BindingType;
@WebService(
portName="CallbackPort",
serviceName="CallbackService",
targetNamespace="http://example.oracle.com",
endpointInterface=
"examples.webservices.callback.callbackservice.CallbackPortType",
wsdlLocation="/wsdls/Callback.wsdl")
@BindingType(value="http://schemas.xmlsoap.org/wsdl/soap/http")
public class CallbackWS implements
examples.webservices.callback.callbackservice.CallbackPortType {
public CallbackWS() {
}
public java.lang.String callback(java.lang.String arg0) {
return arg0.toUpperCase();
}
}
Updating the build.xml File for the Target Web Service
You update a build.xml
file to generate a target web service that invokes the callback web service by adding taskdefs
and a build-target
target that resemble the following example. See the description after the example for details.
<taskdef name="jwsc" classname="weblogic.wsee.tools.anttasks.JwscTask" /> <target name="build-target"> <jwsc srcdir="src" destdir="${ear-dir}" listfiles="true"> <jws file="TargetImpl.java" compiledWsdl="${cowDir}/target/Target_wsdl.jar" type="JAXWS"> <WLHttpTransport contextPath="target" serviceUri="TargetService"/> </jws> <clientgen type="JAXWS" wsdl="Callback.wsdl" packageName="examples.webservices.callback.callbackservice"/> </jwsc> <zip destfile="${ear-dir}/jws.war" update="true"> <zipfileset dir="src/examples/webservices/callback" prefix="wsdls"> <include name="Callback*.wsdl"/> </zipfileset> </zip> </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:
-
<clientgen>
child element of the<jws>
element to generate and compile theService
interface stubs for the deployedCallbackService
web service. Thejwsc
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 theTartgetImpl
JWS file imports and uses one of the generated classes. -
<zip>
element to include the WSDL for theCallbackService
service in the WAR file so that other web services can access the WSDL from the following URL:http://${wls.hostname}:${wls.port}/callback/wsdls/Callback.wsdl
.
For more information about jwsc
, see Running the jwsc WebLogic Web Services Ant Task in Developing JAX-RPC Web Services for Oracle WebLogic Server.