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:

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.

How the Headers Work

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.

What to Look for in a Conversational Web Service's WSDL File

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:

By looking at this excerpt, you can see that:

  <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>

Related Topics

Life of a Conversation

Overview: Conversations

How Do I: Tell Developers of Non-WebLogic Workshop Clients How to Participate in Conversations?