Conversing with Non-Workshop Clients
For services you build with WebLogic Workshop, adding support for conversations is easy. At design time, you simply set the conversation property's phase attribute for your service's methods and callbacks. At run time, WebLogic Server turns these properties into headers within the SOAP messages that web services exchange.
For clients built with tools other than WebLogic Workshop, however, adding conversation support involves a different process. Developers typically add support for conversations with your service by writing their own code to set and retrieve the required SOAP headers. In particular, the headers provide a way for clients to send and receive a conversation ID and URL to which your service should send callbacks. These headers are associated with the publicly exposed methods and callbacks of your service — known as operations.
Note: If you are developing web services with .NET (or need to interoperate with .NET services), you may be interested in ConversationClient.asmx.cs, a sample available in the interop folder of the WebLogic Workshop samples project. This file contains code for a web service client written in C#. For more information, see .NET Client Sample.
The three SOAP headers related to conversations are:
<StartHeader> — The client sends this header with the call to a method marked to "start" a conversation. The <StartHeader> contains <conversationID> and <callbackLocation> elements.
<ContinueHeader> — The client sends this with any subsequent calls to the web service's methods. It contains the conversation ID the client used to start the conversation.
<CallbackHeader> — The client receives this header when it receives a callback from the web service. The <CallbackHeader> includes the conversation ID the client used to start the conversation.
As you can see, one piece of information all of the headers carry is the conversation ID. The client sends in the conversation ID with the first request. The same ID is then passed back and forth between the client and your service for each of their exchanges. This way, both know which initial request the message they're currently receiving is related to.
A client's first request, which begins a conversation, is always sent to a method marked to "start" the conversation. The SOAP message for this request must include the <StartHeader> header. In the message, this header looks like the following:
<SOAP-ENV:Header> <StartHeader xmlns="http://www.openuri.org/2002/04/soap/conversation/"> <conversationID>someUniqueIdentifier</conversationID> <callbackLocation>http://www.mydomain.com/myClient</callbackLocation> </StartHeader> </SOAP-ENV:Header>
The <StartHeader> element simply contains the header information. The XML namespace must be used as it is shown here.
The <conversationID> element is technically optional. If it is omitted, WebLogic Server will invent one for use locally. However, the client will have no way of knowing what this conversation ID is if they don't send it. This means that they will be unable to correlate any responses received with the original request. For this reason, the client should only omit the conversation ID if they do not expect any further conversation with the web service.
The <callbackLocation> element, also optional, contains the URL to which callbacks should be sent. The client need send this only if it expects to handle a callback from the web service. When this value is received by the WebLogic Workshop web service, it is stored for later use by WebLogic Server.
After the first request, the client either continues its side of the
conversation by calling additional methods of the web service or receives
callbacks from the web service. Each subsequent call to the web service
must include the <ContinueHeader>. Note that this means even calls
to web service methods marked to "finish" the conversation must
include the <ContinueHeader>. After the conversation begins, the
web service owns its duration —
the web service is responsible for finishing it and for sending a useful
response to the client.
The <ContinueHeader> might look like the following:
<SOAP-ENV:Header>
<ContinueHeader xmlns="http://www.openuri.org/2002/04/soap/conversation/">
<conversationID>theUniqueIdentifierSentWithTheStartHeader</conversationID>
</ContinueHeader>
</SOAP-ENV:Header>
In order to correctly correlate this call with the first, the <conversationID> used here must be the same as the ID sent with the <StartHeader>.
Finally, the client may be designed to handle callbacks from the web
service. This means that the client software includes an operation capable
of receiving the message sent by the WebLogic Workshop web service's callback.
How this is implemented differs depending on the technology used to build
the client. In general, though, the message sent with a callback contains
the callback's parameter values.
The callback message also contains the <CallbackHeader>. The <CallbackHeader>
includes—yes,
you guessed it—the
conversation ID. It might look like the following:
<SOAP-ENV:Header>
<CallbackHeader xmlns="http://www.openuri.org/2002/04/soap/conversation/">
<conversationID>theUniqueIdentifierSentWithTheStartHeader</conversationID>
</CallbackHeader>
</SOAP-ENV:Header>
Notice that there is no "finish" header. The conversation is over when the web service finishes it. This may be through execution of an operation (method or callback) marked with the conversation phase set to "finish". The web service can also call the finish method of the JwsContext interface (something it might do in the event of an exception). Using the WSDL file for the web service, the client knows which operations are designed to finish the conversation.
By looking at the WSDL file generated from a WebLogic Workshop service, someone developing software that may be a client of the service can discover which of the service's operations start, continue or finish a conversation. They can also see which SOAP header each operation requires.
The following excerpt is from a WSDL generated from the Conversation.jws web service in the WebLogic Workshop samples project. In this example:
The name of each operation (method and callback) is highlighted in bold.
The phase attribute describing the operation's role in a conversation is highlighted in blue.
The part attribute describing which header the service will receive (as an "input" header) and which it will send (as an "output" header) is highlighted in red.
By looking at this excerpt, you can see that:
The startRequest operation starts the conversation and requires a <StartHeader>.
The getRequestStatus operation continues the conversation and requires a <ContinueHeader>.
The terminateRequest operation finishes the conversation and requires a <ContinueHeader>.
The onResultReady operation finishes the conversation and sends a <CallbackHeader>.
<binding name="ConversationSoap" type="s0:ConversationSoap"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> <operation name="startRequest"> <soap:operation soapAction="http://www.openuri.org/startRequest" style="document" /> <cw:transition phase="start" /> <input> <soap:body use="literal" /> <soap:header wsdl:required="true" message="s0:StartHeader_literal" part="StartHeader" use="literal" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" /> </input> <output> <soap:body use="literal" /> </output> </operation> <operation name="getRequestStatus"> <soap:operation soapAction="http://www.openuri.org/getRequestStatus" style="document" /> <cw:transition phase="continue" /> <input> <soap:body use="literal" /> <soap:header wsdl:required="true" message="s0:ContinueHeader_literal" part="ContinueHeader" use="literal" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" /> </input> <output> <soap:body use="literal" /> </output> </operation> <operation name="terminateRequest"> <soap:operation soapAction="http://www.openuri.org/terminateRequest" style="document" /> <cw:transition phase="finish" /> <input> <soap:body use="literal" /> <soap:header wsdl:required="true" message="s0:ContinueHeader_literal" part="ContinueHeader" use="literal" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" /> </input> <output> <soap:body use="literal" /> </output> </operation> <operation name="onResultReady"> <soap:operation soapAction="http://www.openuri.org/onResultReady" style="document" /> <cw:transition phase="finish" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> <soap:header wsdl:required="true" message="s0:CallbackHeader_literal" part="CallbackHeader" use="literal" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" /> </output> </operation> </binding>
How Do I: Tell Developers of Non-WebLogic Workshop Clients How to Participate in Conversations?