Visualforce ページでの長時間コールアウトの実行
次の図は、Visualforce ページから開始する非同期コールアウトの実行パスを示します。ユーザが Visualforce ページで Web サービスから情報を要求するアクションを呼び出します (ステップ 1)。アプリケーションサーバは、コールアウト要求を継続サーバに渡してから Visualforce ページに応答します (ステップ 2 ~ 3)。継続サーバは、要求を Web サービスに送信し、応答を受信します (ステップ 4 ~ 7)。その後で応答をアプリケーションサーバに戻します (ステップ 8)。最後に、応答が Visualforce ページに返されます (ステップ 9)。
非同期コールアウトを使用するメリットがある典型的な Salesforce アプリケーションとして、ボタンが設定された Visualforce ページがあります。ユーザはこのボタンをクリックして、外部 Web サービスからデータを取得します。たとえば、Visualforce ページで特定の製品の保証情報を Web サービスから取得する場合があります。組織内の何千人ものエージェントがこのページを使用できます。そのため、そのうちの 100 人のエージェントが同じボタンをクリックして、製品の保証情報を同時に処理することがあります。こうした 100 件の同時アクションにより、長時間要求の同時実行数に対する 10 という制限が超過します。ただし、非同期コールアウトを使用すると、要求がこの制限の対象にならず、実行されます。
次のアプリケーション例では、ボタンアクションは Apex コントローラメソッドで実装されます。このアクションメソッドは、Continuation を作成して返します。要求がサービスに送信された後、Visualforce 要求は一時停止されます。ユーザは応答が返されるまで待ってから、ページを使用して処理を進め、新しいアクションを呼び出す必要があります。外部サービスが応答を返すと、Visualforce 要求が再開され、ページはこの応答を受け取ります。
これは同じアプリケーションの Visualforce ページです。このページには、このページに関連付けられたコントローラの startRequest メソッドを呼び出すボタンが含まれています。継続の結果が返されてコールバックメソッドが呼び出された後、ボタンは outputText コンポーネントを再度表示してレスポンスボディを表示します。
1<apex:page controller="ContinuationController" showChat="false" showHeader="false">
2 <apex:form >
3 <!-- Invokes the action method when the user clicks this button. -->
4 <apex:commandButton action="{!startRequest}"
5 value="Start Request" reRender="result"/>
6 </apex:form>
7
8 <!-- This output text component displays the callout response body. -->
9 <apex:outputText id="result" value="{!result}" />
10</apex:page>次は、Visualforce ページに関連付けられている Apex コントローラです。このコントローラには、アクションおよびコールバックメソッドが含まれます。
1public with sharing class ContinuationController {
2 // Unique label corresponding to the continuation
3 public String requestLabel;
4 // Result of callout
5 public String result {get;set;}
6 // Callout endpoint as a named credential URL
7 // or, as shown here, as the long-running service URL
8 private static final String LONG_RUNNING_SERVICE_URL =
9 '<Insert your service URL>';
10
11 // Action method
12 public Object startRequest() {
13 // Create continuation with a timeout
14 Continuation con = new Continuation(40);
15 // Set callback method
16 con.continuationMethod='processResponse';
17
18 // Create callout request
19 HttpRequest req = new HttpRequest();
20 req.setMethod('GET');
21 req.setEndpoint(LONG_RUNNING_SERVICE_URL);
22
23 // Add callout request to continuation
24 this.requestLabel = con.addHttpRequest(req);
25
26 // Return the continuation
27 return con;
28 }
29
30 // Callback method
31 public Object processResponse() {
32 // Get the response by using the unique label
33 HttpResponse response = Continuation.getResponse(this.requestLabel);
34 // Set the result variable that is displayed on the Visualforce page
35 this.result = response.getBody();
36
37 // Return null to re-render the original Visualforce page
38 return null;
39 }
40}