# Conversation.jws Sample

This topic inludes the source code for the Conversation.jws Sample.

## Sample Location

This sample is located in the following directory in your WebLogic Workshop installation:

BEA_HOME/weblogic81/samples/workshop/SamplesApp/WebServices/async/

## Sample Source Code

`001 package async; 002 003 import com.bea.control.JwsContext; 004 005 /** 006 * <p>Demonstrates use of the @jws:conversation tag to manage the lifetime of the service 007 * and provide data persistence and message correlation.</p> 008 * 009 * <p>Remember that multiple clients might invoke a web service simultaneously. When the 010 * web service stores data relevant to the client or calls additional services 011 * in order to process a client's request, the service must be able to process returned 012 * data from the external services in the context of the specific client it relates 013 * to. This is all automatic when conversations are used.</p> 014 * 015 * <p>This service uses an external service that is asynchronous, but exposes polling 016 * methods in addition to callbacks so that a client that can't accept callbacks 017 * can use it.</p> 018 * 019 * <p>Remember that not all clients are capable of accepting callbacks. Specifically, 020 * clients operating from behind firewalls may not be able to receive asynchronous 021 * callbacks. You may wish to provide a synchronous interface, like this one, 022 * for such clients. If a client can accept callbacks, it must send a callbackURL 023 * as part of any "start conversation" method invocation. The callbackURL is 024 * available via the getCallbackLocation method of the JwsContext interface, 025 * which is available in all WebLogic web services.</p> 026 * 027 * <p>To see the behavior in the Test View, invoke startRequest and then getRequestStatus 028 * several times quickly. Examine the results of the calls to testHelloAsync. 029 * The result of getRequestStatus will change once the timer in HelloWorldAsync 030 * has expired.</p> 031 * @common:target-namespace namespace="http://workshop.bea.com/Conversation" 032 */ 033 public class Conversation implements com.bea.jws.WebService 034 { 035 /** 036 * @common:control 037 */ 038 private HelloWorldAsyncControl helloAsync; 039 040 /** 041 * @common:context 042 */ 043 JwsContext context; 044 045 /** 046 * <p>This variable holds what the HelloWorldAsync service has sent back, if anything. 047 * By designating the methods of this web service as part of a conversation 048 * with the @common:conversation tags, member variables of this web service 049 * automatically become persistent for the duration of the conversation.</p> 050 */ 051 private String helloAsyncReturn; 052 053 /** 054 * <p>This variable holds the callbackURL of the client. It is obtained from the 055 * JwsContext interface during the "start" method of the conversation. If the client 056 * does not supply a callback URL, then callbacks cannot be sent to the client. 057 * 058 * In this web service, we'll assume that if the client can't accept callbacks it 059 * will use the polling interface (getRequestStatus) to get the current state and 060 * it will use terminateRequest when the client is done using this web service.</p> 061 */ 062 private String callbackURL = null; 063 064 public Callback callback; 065 066 public interface Callback 067 { 068 /** 069 * Callback to invoke on the client when the external service 070 * returns its result. Will only be called it the client can 071 * accept callbacks and told us where to send them. 072 * 073 * If this callback is used, it implicitly terminates the 074 * conversation with no action required on the part of the 075 * client. 076 * 077 * @jws:conversation phase="finish" 078 */ 079 public void onResultReady(String result); 080 } 081 082 083 084 /** 085 * <p>Starts the conversation and makes a request to the HelloWorldAsync service. 086 * To continue the sample after calling this method, click the conversation ID in the 087 * log, then select getRequestStatus until the request is fulfilled. Then click 088 * terminateRequest.</p> 089 * 090 * <p>Pass in <b>false</b> for useCallbacks to simulate a client that cannot accept 091 * callbacks.</p> 092 * 093 * <p>Pass in <b>true</b> for useCallbacks to allow callbacks.</p> 094 * 095 * @common:operation 096 * @jws:conversation phase="start" 097 */ 098 public void startRequest(boolean useCallbacks) 099 { 100 /* 101 * The servlet that underlies Test View can receive callbacks, so 102 * we can't demonstrate a client that cannot accept callbacks unless 103 * we provide an explicit way for the client to say not to use them. 104 * If you specify 'false' for useCallbacks in Test View when using this 105 * web service, it will behave as though the client cannot accept 106 * callbacks. 107 */ 108 if( useCallbacks ) { 109 callbackURL = context.getCallbackLocation(); 110 } 111 // start the HelloWorldAsync service. 112 helloAsync.HelloAsync(); 113 } 114 115 /** 116 * <p>getRequestStatus is used to poll Conversation.jws to determine whether 117 * we've heard back from HelloWorldAsync.</p> 118 * 119 * @common:operation 120 * @jws:conversation phase="continue" 121 */ 122 public String getRequestStatus() 123 { 124 if (helloAsyncReturn == null) 125 return "HelloAsync has not yet returned it's message"; 126 else 127 return "HelloAsync said: '" + helloAsyncReturn + "'"; 128 } 129 130 /** 131 * <p>Used to tell Conversation.jws that the current conversation is 132 * no longer needed.</p> 133 * 134 * @common:operation 135 * @jws:conversation phase="finish" 136 */ 137 public void terminateRequest() 138 { } 139 140 /** 141 * <p>Handler for HelloWorldAsync's HelloResult callback.</p> 142 * 143 * <p>Store HelloWorldAsync's response in a member variable so that future calls to 144 * testHelloAsync will give the current status.</p> 145 */ 146 public void helloAsync_onHelloResult(java.lang.String hello) 147 { 148 helloAsyncReturn = hello; 149 150 /* 151 * If the client can accept callbacks, use the callback to send the result. 152 * Since onResultReady is marked phase="finish", the conversation will be 153 * terminated after this call with no further action required from the 154 * client. 155 */ 156 if( callbackURL != null ) { 157 callback.onResultReady(hello); 158 } 159 } 160 }`