Oracle WebLogic Server JAX-WS Webサービスの高度な機能のプログラミング

12c リリース1(12.1.1)

B65943-02(原本部品番号:E24965-02)

目次

タイトルおよび著作権情報

はじめに

- ドキュメントのアクセシビリティについて

- 表記規則

1 概要

2 Web Services Addressingの使用

- WS-Addressingの概要

- WebサービスでのWS-Addressingの有効化

- WebサービスでのWS-Addressingの有効化(Javaから始める場合)

- WebサービスでのWS-Addressingの有効化(WSDLから始める場合)

- Webサービス・クライアントでのWS-Addressingの有効化

- Webサービス・クライアントでのWS-Addressingの明示的な有効化

- Webサービス・クライアントでのWS-Addressingの暗黙的な有効化

- Webサービス・クライアントでのWS-Addressingの無効化

- WS-AddressingのActionプロパティの関連付け

- WS-AddressingのActionプロパティの明示的な関連付け(Javaから始める場合)

- WS-AddressingのActionプロパティの明示的な関連付け(WSDLから始める場合)

- WS-AddressingのActionプロパティの暗黙的な関連付け

- 匿名WS-Addressingの構成

3 Webサービス・クライアントを開発する手順

- Webサービス・クライアントを開発する手順

- 非同期Webサービス・クライアントを開発する手順

4 Webサービスの非同期呼出し

- Webサービスの非同期呼出しの概要

- Webサービスを非同期に呼び出す手順

- Webサービスを非同期に呼び出すためのサーバーの構成

- Webサービスを非同期に呼び出すためのクライアント・アーティファクトの構築

- スケーラブルな非同期JAX-WSクライアントの開発(非同期クライアント・トランスポート)

- 非同期クライアント・トランスポート機能の有効化と構成

- 非同期レスポンス・エンドポイントのアドレスの構成

- 非同期レスポンス・エンドポイントのReplyToヘッダーとFaultToヘッダーの構成

- 非同期レスポンス・エンドポイントのコンテキスト・パスの構成

- 非同期レスポンス・エンドポイントの公開

- 同期操作用の非同期クライアント・トランスポートの構成

- 非同期ハンドラ・インタフェースの開発

- レスポンスへのユーザー定義リクエスト・コンテキストの伝播

- ファイアウォールの内側からの非同期Webサービス・クライアントの使用(接続作成)

- Webサービスでの接続作成の有効化と構成

- Webサービスの接続作成WS-Policyファイルの作成(オプション)

- 接続作成を有効にするためのJWSファイルのプログラミング

- Webサービス・クライアントでの接続作成の有効化と構成

- 接続作成メッセージ送信の有効時間の構成

- ポーリング間隔の構成

- 指数関数的バックオフの構成

- 同期メソッドのトランスポートとしての接続作成の構成

- JAX-WS参照実装の使用

- レスポンスへのリクエスト・コンテキストの伝播

- 非同期Webサービス呼出しのモニタリング

- 非同期Webサービス・メッセージングのクラスタリングの考慮事項

5 信頼性のあるWebサービスとクライアントを開発する手順

- 信頼性のあるWebサービス・クライアントを開発する手順

- 信頼性のあるWebサービスを開発する手順

- ファイアウォールの内側から信頼性のあるWebサービスにアクセスする手順(接続作成)

- 信頼性のあるWebサービスを保護する手順

6 Webサービスの信頼性のあるメッセージングの使用

- Webサービスの信頼性のあるメッセージングの概要

- WS-Policyを使用した信頼性のあるメッセージング・ポリシーのアサーションの指定

- 信頼性のあるメッセージングでサポートされるトランスポート・タイプ

- 信頼性のあるメッセージ・シーケンスのライフサイクル

- 信頼性のあるメッセージングの障害リカバリのシナリオ

- リクエストが到着する前にRM宛先がダウンする

- リクエストが行われた後でRM送信元がダウンする

- リクエストが到着した後でRM宛先がダウンする

- バッファなしの信頼性のあるWebサービスでの障害シナリオ

- 信頼性のあるWebサービスの作成および呼出し手順

- 送信元と宛先のWebLogic Serverインスタンスの構成

- Webサービスの信頼性のあるメッセージングのWS-Policyファイルの作成

- WS-ReliableMessagingポリシー・アサーション・バージョン1.2と1.1を使用したカスタムWS-Policyファイルの作成

- WS-ReliableMessagingポリシー・アサーション・バージョン1.0を使用したカスタムWS-Policyファイルの作成(非推奨)

- 複数のポリシー選択肢の使用

- 信頼性のあるJWSファイルに関するプログラミングのガイドライン

- Webサービス・クライアントからの信頼性のあるWebサービスの呼出し

- 信頼性のあるメッセージングの構成

- WebLogic Serverでの信頼性のあるメッセージングの構成

- 管理コンソールを使用する

- WLSTの使用

- Webサービス・エンドポイントでの信頼性のあるメッセージングの構成

- Webサービス・クライアントでの信頼性のあるメッセージングの構成

- 基本の再送信間隔の構成

- WebLogic ServerまたはWebサービス・エンドポイントでの基本の再送信間隔の構成

- Webサービス・クライアントでの基本の再送信間隔の構成

- 再送信間隔の指数関数的バックオフの構成

- WebLogic ServerまたはWebサービス・エンドポイントでの再送信間隔の指数関数的バックオフの構成

- Webサービス・クライアントでの再送信間隔の指数関数的バックオフの構成

- 順序の有効期限の構成

- WebLogic ServerまたはWebサービス・エンドポイントでの順序の有効期限の構成

- Webサービス・クライアントでの順序の有効期限の構成

- 非アクティブ・タイムアウトの構成

- WebLogic ServerまたはWebサービス・エンドポイントでの非アクティブ・タイムアウトの構成

- Webサービス・クライアントでの非アクティブ・タイムアウトの構成

- Webサービスのバッファなし宛先の構成

- 確認応答の間隔の構成

- 信頼性エラー・リスナーの実装

- 信頼性のあるメッセージ・シーケンスのライフサイクルの管理

- 信頼性のあるシーケンスの管理

- 信頼性のあるシーケンスIDの取得および設定

- 信頼性のあるシーケンスの状態へのアクセス

- クライアントIDの管理

- 確認応答済みリクエストの管理

- メッセージに関する情報へのアクセス

- 信頼性のあるシーケンスでの最後のメッセージの識別

- 信頼性のあるシーケンスを閉じる

- 信頼性のあるシーケンスの終了

- 新しいメッセージ・シーケンスを開始するためのクライアントのリセット

- Webサービスの信頼性のあるメッセージングの監視

- ビジネス作業単位へのメッセージのグループ化(バッチ化)

- 信頼性のあるWebサービスを再デプロイする際にクライアント側で考慮すべき事項

- WebLogic Web サービスの信頼性のあるメッセージングとの相互運用性

7 Webサービス永続性の管理

- Webサービス永続性の概要

- Webサービス永続性を構成する手順

- Webサービス永続性の構成

- 論理ストアの構成

- Webサービス・エンドポイントのWebサービス永続性の構成

- Webサービス・クライアントのWebサービス永続性の構成

- クラスタでのWebサービス永続性の使用

- Webサービス永続性のクリーンアップ

8 Webサービスのメッセージ・バッファリングの構成

- メッセージ・バッファリングの概要

- メッセージ・バッファリングの構成

- リクエスト・キューの構成

- レスポンス・キューの構成

- メッセージの再試行回数と遅延の構成

9 クラスタ内のWebサービスの管理

- Webサービス・クラスタでのルーティングの概要

- クラスタでのルーティングのシナリオ

- シナリオ1: 単一サーバーへのWebサービス・レスポンスのルーティング

- シナリオ2: ルーティング情報を使用した単一サーバーへのWebサービス・レスポンスのルーティング

- シナリオ3: IDを使用した単一サーバーへのWebサービス・レスポンスのルーティング

- Webサービス・クラスタでのルーティングの仕組み

- 送信するリクエストへのルーティング情報の追加

- 受信したリクエストのルーティング情報の検出

- クラスタ内でのリクエストのルーティング

- フロントエンドSOAPルーターでのルーティング・マップの保持

- X-weblogic-wsee-storetoserver-list HTTPレスポンス・ヘッダー

- X-weblogic-wsee-storetoserver-hash HTTPレスポンス・ヘッダー

- クラスタ内のWebサービスの構成

- WebLogicクラスタの設定

- クラスタ環境におけるWebサービスの高度な機能に必要なドメイン・リソースの構成

- フロントエンドSOAPルーターの拡張によるWebサービスのサポート

- Webサービス原子性トランザクション・メッセージのルーティングの有効化

- Webサービスの接続作成メッセージのルーティングの有効化

- フロントエンドSOAPルーターのIDの構成

- クラスタのルーティング・パフォーマンスのモニター

10 Webサービス原子性トランザクションの使用

- Webサービス原子性トランザクションの概要

- Webサービスの高度な機能に必要なドメイン・リソースの構成

- Webサービスに対するWebサービス原子性トランザクションの有効化

- JWSファイルでの@Transactionalアノテーションの使用

- 例: Webサービス・クラスでの@Transactionalアノテーションの使用

- 例: Webサービス・メソッドでの@Transactionalアノテーションの使用

- 例: @TransactionalアノテーションとEJB @TransactionAttributeアノテーションの併用

- WSDLから開始するWebサービス原子性トランザクションの有効化

- Webサービス・クライアントに対するWebサービス原子性トランザクションの有効化

- @Transactionalアノテーションと@WebServiceRefアノテーションの併用

- TransactionalFeatureをクライアントに渡す

- 管理コンソールを使用したWebサービス原子性トランザクションの構成

- コーディネータと参加者の間で交換されるメッセージの保護

- Webサービス原子性トランザクションの有効化および構成

- クラスタ環境でのWebサービス原子性トランザクションの使用

- Webサービス原子性トランザクションのその他の使用例

11 Webサービスのエンドポイントのパブリッシュ

12 コールバックの使用

- コールバックの概要

- コールバック実装のサンプル

- コールバックのプログラミング手順

- ターゲットWebサービスのプログラミングのガイドライン

- コールバック・クライアントWebサービスのプログラミングのガイドライン

- コールバックWebサービスのプログラミングのガイドライン

- ターゲットWebサービスのbuild.xmlファイルの更新

13 バイナリ・データ転送の最適化

- MTOM/XOPを使用したバイナリ・データ転送の最適化

- データ型のアノテーションの追加

- データ型のアノテーションを追加する: Javaから始める場合

- データ型のアノテーションを追加する: WSDLから始める場合

- WebサービスでMTOMの有効化

- アノテーションを使用してWebサービスでMTOMの有効化

- WS-Policyファイルを使用してWebサービスでMTOMの有効化

- クライアントでMTOMの有効化

- 添付ファイルのしきい値の設定

- SOAP添付ファイルのストリーミング

- クライアント側のサンプル

- サーバー側のサンプル

- SOAP添付ファイルのストリーミングの構成

- サーバーでSOAP添付ファイルのストリーミングの構成

- クライアントでSOAP添付ファイルのストリーミングの構成

- swaRefを使用した添付ファイル付きSOAPメッセージの送信

14 動的プロキシ・クライアントの開発

- 静的プロキシ・クライアントと動的プロキシ・クライアントの概要

- 動的プロキシ・クライアントの開発手順

- WSDLの場所を指定する際のその他の考慮事項

15 XMLカタログの使用

- XMLカタログの概要

- XMLカタログの定義と参照

- 外部XMLカタログの定義

- 外部XMLカタログ・ファイルの作成

- 外部XMLカタログ・ファイルの参照

- XMLカタログを埋め込み

- 埋め込みXMLカタログの作成

- 埋め込みXMLカタログの参照

- クライアント・ランタイムでのXMLカタログの無効化

- XMLリソースのローカル・コピーの取得

16 SOAPフォルトを使用した例外処理

- SOAPフォルトを使用した例外処理の概要

- SOAPフォルト要素のコンテンツ

- SOAP 1.2 <Fault>要素のコンテンツ

- SOAP 1.1 <Fault>要素のコンテンツ

- モデル化されたフォルトの使用

- カスタム例外の作成と使用

- モデル化されたフォルトのWSDLファイルにおけるマッピングの仕組み

- SOAPメッセージによるフォルト通知の仕組み

- Webサービス・クライアントの作成

- 生成されたJava例外クラスの確認

- 生成されたJavaフォルトBeanクラスの確認

- クライアント側のサービス実装の確認

- クライアント実装クラスの作成

- モデル化されていないフォルトの使用

- 例外処理プロセスのカスタマイズ

- SOAPフォルトからのスタック・トレースの無効化

- その他の例外

17 SOAPメッセージ・ハンドラの作成と使用

- SOAPメッセージ・ハンドラの概要

- サーバー側SOAPメッセージ・ハンドラの追加:主な手順

- クライアント側SOAPメッセージ・ハンドラの追加:主な手順

- SOAPメッセージ・ハンドラおよびハンドラ・チェーンの設計

- サーバー側ハンドラの実行

- クライアント側ハンドラの実行

- SOAPメッセージ・ハンドラの作成

- SOAPハンドラのサンプル

- 論理ハンドラのサンプル

- Handler.handleMessage()メソッドの実装

- Handler.handleFault()メソッドの実装

- Handler.close()メソッドの実装

- メッセージ・コンテキスト・プロパティの値とメソッドの使用

- SAAJを使用したSOAPリクエスト・メッセージおよびレスポンス・メッセージの直接操作

- SOAPPartオブジェクト

- AttachmentPartオブジェクト

- SOAPメッセージ・ハンドラで画像添付ファイルの操作

- JWSファイルでのハンドラ・チェーンの構成

- ハンドラ・チェーン構成ファイルの作成

- Webサービスのコンパイルと再ビルド

- クライアント側SOAPメッセージ・ハンドラの構成

18 SOAPヘッダーの送受信

- SOAPヘッダーの送受信の概要

- WSBindingProviderを使用したSOAPヘッダーの送信

- WSBindingProviderを使用したSOAPヘッダーの受信

19 XMLメッセージ・レベルでの操作

- Webサービス・プロバイダベース・エンドポイントおよびディスパッチ・クライアントの概要

- XMLレベルでの処理のための使用モードとメッセージ・フォーマット

- Webサービス・プロバイダベース・エンドポイントの開発(Javaから始める場合)

- 同期プロバイダベース・エンドポイントの開発

- 非同期プロバイダベース・エンドポイントの開発

- メッセージ・フォーマットの指定

- JWSファイルによるWebサービス・プロバイダの実装の指定(@WebServiceProviderアノテーション)

- 使用モードの指定(@ServiceModeアノテーション)

- 同期プロバイダベース・エンドポイントのinvoke()メソッドの定義

- 非同期プロバイダベース・エンドポイントのinvoke()メソッドの定義

- 非同期プロバイダベース・エンドポイントのコールバック・ハンドラの定義

- Webサービス・プロバイダベース・エンドポイントの開発(WSDLから始める場合)

- プロバイダベース・エンドポイントでのSOAPハンドラの使用

- Webサービス・ディスパッチ・クライアントの開発

- Webサービス・ディスパッチ・クライアントの例

- ディスパッチ・インスタンスの作成

- Webサービス操作の呼出し

20 XML over HTTPを使用するWebサービスのプログラミング

- XML over HTTPを使用するWebサービスのプログラミングの概要

- XML over HTTPを使用するWebサービスのプログラミングのガイドライン

- クライアントからWebサービスにアクセスする

- XML over HTTPを使用するWebサービスの保護

21 HTTPセッションを使用したステートフルJAX-WS Webサービスのプログラミング

- ステートフルWebサービスの概要

- サーバーでHTTPセッションにアクセスする

- クライアントでのHTTPセッションの有効化

- セッション状態レプリケーションを使用してクラスタ内のステートフル・サービスを開発する

- JAX-WS RI @ステートフル拡張に関する注意

A Webサービスの信頼性のあるメッセージングと接続作成のためのあらかじめパッケージ化されたWS-Policyファイル

- DefaultReliability1.2.xml(WS-Policyファイル)

- DefaultReliability1.1.xml (WS-Policyファイル)

- DefaultReliability.xml WS-Policyファイル(WS-Policy)[非推奨]

- LongRunningReliability.xml WS-Policyファイル(WS-Policy)[非推奨]

- Mc1.1.xml(WS-Policyファイル)

- Mc.xml(WS-Policyファイル)

- Reliability1.2_ExactlyOnce_WithMC1.1.xml(WS-Policyファイル)

- Reliability1.2_SequenceSTR.xml(WS-Policyファイル)

- Reliability1.1_SequenceSTR.xml(WS-Policyファイル)

- Reliability1.2_SequenceTransportSecurity.xml(WS-Policyファイル)

- Reliability1.1_SequenceTransportSecurity.xml(WS-Policyファイル)

- Reliability1.0_1.2.xml(WS-Policyファイル)

- Reliability1.0_1.1.xml(WS-Policy.xmlファイル)

B 信頼性のあるメッセージングのバッチ化のためのクライアント・ラッパー・クラスの例

Oracle® Fusion Middleware

Oracle WebLogic Server JAX-WS Webサービスの高度な機能のプログラミング

12c リリース1(12.1.1)

B65943-02(原本部品番号:E24965-02)

2012年1月

JAX-WS WebサービスでWeb Services Reliable Messaging(WS-ReliableMessaging)を使用して、クライアント・アプリケーションから別のアプリケーション・サーバー上で実行されているWebサービスを信頼性のある方法で呼び出し、2つのエンドポイント間で保証付きのメッセージ配信を行う方法について説明した、ソフトウェア開発者向けのドキュメント。

Oracle Fusion Middleware Oracle WebLogic Server JAX-WS Webサービスの高度な機能のプログラミング, 12c リリース1(12.1.1)

B65943-02

Copyright © 2007, 2012, Oracle and/or its affiliates.All rights reserved.

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、Oracleまでご連絡ください。

このソフトウェアまたは関連ドキュメントが、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供される場合は、次のNoticeが適用されます。

U.S. GOVERNMENT RIGHTS Programs, software, databases, and related documentation and technical data delivered to U.S. Government customers are "commercial computer software" or "commercial technical data" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations.As such, the use, duplication, disclosure, modification, and adaptation shall be subject to the restrictions and license terms set forth in the applicable Government contract, and, to the extent applicable by the terms of the Government contract, the additional rights set forth in FAR 52.227-19, Commercial Computer Software License (December 2007).Oracle America, Inc., 500 Oracle Parkway, Redwood City, CA 94065.

このソフトウェアまたはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアまたはハードウェアは、危険が伴うアプリケーション(人的傷害を発生させる可能性があるアプリケーションを含む)への用途を目的として開発されていません。このソフトウェアまたはハードウェアを危険が伴うアプリケーションで使用する際、このソフトウェアまたはハードウェアを安全に使用するために、適切な安全装置、バックアップ、冗長性(redundancy)、その他の対策を講じることは使用者の責任となります。このソフトウェアまたはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、Oracleおよびその関連会社は一切の責任を負いかねます。

OracleおよびJavaはOracleおよびその子会社、関連会社の登録商標です。その他の名称は、それぞれの所有者の商標または登録商標です。

IntelおよびIntel XeonはIntel Corporationの商標または登録商標です。すべてのSPARC商標はライセンスに基づいて使用されるSPARC International, Inc.の商標または登録商標です。AMDロゴおよびAMD Opteronロゴは、Advanced Micro Devicesの商標または登録商標です。UNIXはThe Open Groupの登録商標です。

このソフトウェアまたはハードウェアおよびドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても、一切の責任を負いかねます。

はじめに

ここでは、このドキュメント、『Oracle WebLogic Server JAX-WS Webサービスの高度な機能のプログラミング』で使用されるドキュメント・アクセシビリティ機能および表記規則について説明します。

ドキュメントのアクセシビリティについて

オラクル社のアクセシビリティについての詳細情報は、Oracle Accessibility ProgramのWebサイトhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=docaccを参照してください。

Oracleサポートへのアクセス

Oracleのお客様は、My Oracle Supportにアクセスして電子サポートを受けることができます。詳細は、http://www.oracle.com/pls/topic/lookup?ctx=acc&id=info、またはhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=trs(聴覚に障害のあるお客様向け)を参照してください。

表記規則

このドキュメントでは次の表記規則を使用します。

規則

意味

太字

太字は、操作に関連するGraphical User Interface要素、または本文中で定義されている用語および用語集に記載されている用語を示します。

斜体

イタリックは、ユーザーが特定の値を指定するプレースホルダー変数を示します。

固定幅フォント

固定幅フォントは、段落内のコマンド、URL、サンプル内のコード、画面に表示されるテキスト、または入力するテキストを示します。

1 概要

この章では、Java API for XML Web Services(JAX-WS)を使用してWebLogic Webサービスをプログラミングするソフトウェア開発者のための高度な機能を要約した表を示します。

表1-1 JAX-WSを使用した高度な機能のプログラミング

高度な機能

説明

第2章「Web Services Addressingの使用」

Web Services Addressing(WS-Addressing)を使用してWebサービスとそれに関連付けられたメッセージをトランスポートに依存せずに指定する方法を説明します。

第3章「Webサービス・クライアントを開発する手順」

Webサービス・クライアントを開発するためのベスト・プラクティスを説明します。

第4章「Webサービスの非同期呼出し」

Webサービスを非同期的に呼び出します。

第5章「信頼性のあるWebサービスとクライアントを開発する手順」

非同期で信頼性のあるアプリケーションを開発するためのベスト・プラクティスを説明します。

第6章「Webサービスの信頼性のあるメッセージングの使用」

Webサーバーの信頼性のあるメッセージングを使用して、あるアプリケーション・サーバーで実行しているアプリケーションが別のアプリケーション・サーバーで実行しているWebサービスを確実に呼び出すことができるようにします。両方のサーバーがWS-ReliableMessaging仕様を実装している必要があります。

第7章「Webサービス永続性の管理」

Webサービスの永続性を管理します。Webサービス永続性は、長時間実行するリクエストをサポートし、サーバーの再起動があっても存続するように、高度な機能によって使用されます。

第8章「Webサービスのメッセージ・バッファリングの構成」

Webサービスのメッセージ・バッファリングを構成します。

第9章「クラスタ内のWebサービスの管理」

クラスタ内のWebサービスを使用する際のベスト・プラクティスを説明します。

第10章「Webサービス原子性トランザクションの使用」

Webサービス原子性トランザクションを使用して他の外部トランザクション処理システムとの相互運用性を実現する方法について説明します。

第11章「Webサービスのエンドポイントのパブリッシュ」

実行時に、WebサービスをデプロイせずにWebサービスのエンドポイントをパブリッシュします。

第12章「コールバックの使用」

コールバックをプログラミングしてイベントの発生をWebサービスのクライアントに通知します。

第13章「バイナリ・データ転送の最適化」

MTOM/XOPやストリーミングSOAP添付ファイルを使用してバイナリ・データを送信し、バイナリ・データの転送を最適化します。

第14章「動的プロキシ・クライアントの開発」

実行時に、clientgenを使用することなく、サービス・エンドポイント・インタフェース(SEI)に基づいてWebサービスを動的に呼び出します。

第15章「XMLカタログの使用」

XMLカタログを使用して、ローカルに格納されているバージョンに合わせてネットワーク・リソースを解決します。

第16章「SOAPフォルトを使用した例外処理」

SOAPフォルトおよび例外を処理します。

第17章「SOAPメッセージ・ハンドラの作成と使用」

WebサービスのSOAPメッセージ・ハンドラを作成および構成します。

第19章「XMLメッセージ・レベルでの操作」

XMLメッセージ・レベルで動作するWebサービス・プロバイダ・ベースのエンドポイントとディスパッチ・クライアントを開発します。

第20章「XML Over HTTPを使用するWebサービスのプログラミング」

XML over HTTPを使用してWebサービスをプログラミングします。

第21章「HTTPセッションを使用したステートフルJAX-WS Webサービスのプログラミング」

サービス・コール間の状態を保持するWebサービスを作成します。

付録A「Webサービスの信頼性のあるメッセージングと接続作成のためのあらかじめパッケージ化されたWS-Policyファイル」

信頼性のあるメッセージングをサポートするために使用できる、標準的な信頼性のあるメッセージングのアサーションを含むあらかじめパッケージ化されたWS-Policyファイルについて説明します。

付録B「信頼性のあるメッセージングのバッチ化のためのクライアント・ラッパー・クラスの例」

信頼性のあるメッセージングのバッチ化に使用できるクライアント・ラッパー・クラスの例を提供します。

注意:

Oracle WebLogic ServerのJAX-WS実装は、JAX-WS参照実装(RI)から拡張されて、Glassfish Communityによって開発されます(https://jax-ws.dev.java.net/を参照)。JAX-WS仕様(JSR-224)で定義されたすべての機能は、Oracle WebLogic Serverによって完全にサポートされます。

また、JAX-WS RIにはGlassfish寄稿者によって提供された様々な拡張があります。特にドキュメントされた限り、Oracle WebLogic Serverで使用するためのJAX-WS RI拡張はサポートされません。

WebLogic Webサービスの概要、標準、サンプルおよび関連ドキュメントについては、Webサービスの紹介を参照してください。

JAX-WSはWeb Services Security(WS-Security)1.1をサポートしています。WebLogic Webサービスのセキュリティについては、『Oracle WebLogic Server WebLogic Webサービスの保護』を参照してください。

2 Web Services Addressingの使用

この章では、Java API for XML Web Services(JAX-WS)を使用したWebLogic Webサービスで、Web Services Addressing(WS-Addressing)を使用する方法について説明します。

この章の内容は以下のとおりです。

- WS-Addressingの概要

- WebサービスでのWS-Addressingの有効化

- Webサービス・クライアントでのWS-Addressingの有効化

- WS-AddressingのActionプロパティの関連付け

- 匿名WS-Addressingの構成

WS-Addressingの概要

WS-Addressingは、Webサービスおよびそれに関連するメッセージをアドレッシングするための、トランスポートに依存しないメカニズムを提供します。WS-Addressingを使用すると、エンドポイントはSOAPヘッダー内で一意かつ明確に定義されます。

WS-Addressingには、トランスポートに依存しないアドレッシングを可能にする次の2つの主要なコンポーネントがあります。

- エンドポイント参照(EPR): Webサービス・エンドポイントのアドレッシングに必要な情報を通知します。

- メッセージ・アドレッシング・プロパティ: エンドツーエンドのメッセージ特性(ソースおよび宛先のエンドポイントとメッセージIDへのアドレッシングなど)を通知します。これにより、メッセージに対して基礎となるトランスポートからは独立した共通のアドレッシングが可能になります。
メッセージ・アドレッシング・プロパティには、表2-1に定義されているプロパティを1つ以上含めることができます。wsa:Action以外のプロパティはすべてオプションです。

表2-1 WS-Addressingのメッセージ・アドレッシング・プロパティ

コンポーネント

説明

wsa:To

宛先。指定しない場合は、デフォルトの宛先(http://www.w3.org/2005/08/addressing/anonymous)が設定されます。

wsa:From

ソース・エンドポイント。

wsa:ReplyTo

リプライ・エンドポイント。指定しない場合は、デフォルトのリプライ・エンドポイント(http://www.w3.org/2005/08/addressing/anonymous)が設定されます。

wsa:FaultTo

フォルト・エンドポイント。

wsa:Action

必要なアクション。

WS-Addressingが有効な場合、このプロパティは必須です。これは暗黙的または明示的に構成できます(「WS-Addressing Actionプロパティの関連付け」を参照)。

wsa:MessageID

一意のメッセージID。

wsa:RelatesTo

メッセージに関連付けられたメッセージID。関連メッセージが複数ある場合には、この要素を繰り返すことができます。このプロパティの属性としてRelationshipTypeを指定できます。デフォルト値はhttp://www.w3.org/2005/08/addressing/replyです。

wsa:ReferenceParameters

通知する必要がある参照パラメータ。

例2-1は、では、WS-Addressingを有効にした場合にHTTP 1.2で送信されるSOAP 1.2リクエスト・メッセージを示します。太字で示されているように、WS-Addressingは、一意のメッセージID(wsa:MessageID)、宛先(wsa:To)エンドポイント、リプライ・エンドポイント(wsa:ReplyTo)、および必要なアクション(wsa:Action)を定義するための、トランスポートに依存しないメカニズムを提供します。

例2-1 WS-Addressingを使用したSOAP 1.2メッセージ: リクエスト・メッセージ

<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsa="http://www.w3.org/2005/08/addressing/">
<S:Header>
<wsa:MessageID>
http://example.com/someuniquestring
</wsa:MessageID>
<wsa:ReplyTo
<wsa:Address>http://example.com/Myclient</wsa:Address>
</wsa:ReplyTo>
<wsa:To>
http://example.com/fabrikam/Purchasing
</wsa:To>
<wsa:Action>
http://example.com/fabrikam/SubmitPO
</wsa:Action>
<S:Header>
<S:Body>
...
</S:Body>
</S:Envelope>

このメッセージへのレスポンスは、例2-2のようになります。RelatesToプロパティによってレスポンス・メッセージと元のリクエスト・メッセージが関連付けられます。

例2-2 WS-Addressingを使用しない場合のSOAP 1.2メッセージ: レスポンス・メッセージ

<S:Envelope
xmlns:S="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsa="http://www.w3.org/2005/08/addressing">
<S:Header>
<wsa:MessageID>http://example.com/someotheruniquestring</wsa:MessageID>
<wsa:RelatesTo>http://example.com/someuniquestring</wsa:RelatesTo>
<wsa:To>http://example.com/MyClient/wsa:To>
<wsa:Action>
http://example.com/fabrikam/SubmitPOAck
</wsa:Action>
</S:Header>
<S:Body>
...
</S:Body>
</S:Envelope>

WS-Addressingは、次のWebLogic JAX-WS拡張機能で使用されます。

- 非同期のクライアント・トランスポート(第4章「Webサービスの非同期呼出し」を参照)。

- WS-ReliableMessaging(第6章「Webサービスの信頼性のあるメッセージングの使用」を参照)。

- コールバック(第12章「コールバックの使用」を参照)。

次の項では、WebサービスまたはクライアントでWS-Addressingを有効にし、アクション・プロパティおよびフォルト・プロパティを明示的に定義する方法について説明します。

サポートされているWS-Addressing標準に関する説明

WebLogic Webサービスは、次のWeb Service Addressingの標準をサポートしています。

- W3C WS-Addressing(http://www.w3.org/2002/ws/addr/を参照)

- Member Submission(http://www.w3.org/Submission/ws-addressing/を参照)

この章では、W3C WS-Addressingの使用についてのみを取り上げます。

WebサービスでのWS-Addressingの有効化

デフォルトでは、WS-AddressingはWebサービス・エンドポイントで無効化されています。そのため、受信したWS-Addressingヘッダーはすべて無視されます。WebサービスでのWS-AddressingをJavaまたはWSDLから有効にするには、次の各項に従います。

- WebサービスでのWS-Addressingの有効化(Javaから始める場合)

- WebサービスでのWS-Addressingの有効化(WSDLから始める場合)

Webサービス・エンドポイントでWS-Addressingを有効にすると次のようになります。

- すべてのWS-Addressingヘッダーがエンドポイントで認識されます。つまり、mustUnderstandを有効にしてWS-Addressingヘッダーを受信した場合、フォルトはスローされません。

- 受信したWS-Addressingヘッダーは、次のことを確認するために検証されます。

- 構文が正しいか

- 要素数が正しいか

- SOAPヘッダーのwsa:Actionヘッダーが操作で必要なものと一致しているか

- クライアントに返されるレスポンス・メッセージには必要なWS-Addressingヘッダーが格納されます。

WebサービスでのWS-Addressingの有効化(Javaから始める場合)

WebサービスでのWS-AddressingをJavaから有効にするには、Webサービス・クラスでjava.xml.ws.soap.Addressingアノテーションを使用します。必要に応じて、表2-2に定義されているBoolean属性を1つ以上渡すことができます。

表2-2 @Addressingアノテーションの属性

属性

説明

enabled

WS-Addressingを有効にするかどうかを指定します。有効な値は、true(有効)およびfalse(無効)です。この属性のデフォルト値はtrueです。

required

インバウンド・メッセージに対してWS-Addressingルールを適用するかどうかを指定します。有効な値は、true(適用する)およびfalse(適用しない)です。falseに設定すると、WS-Addressingが有効かどうかを確認するためのチェックがインバウンド・メッセージに対して行われ、有効な場合はルールが適用されます。この属性のデフォルト値はfalseです。

有効にすると、wsaw:UsingAddressing要素が、対応するwsdl:binding要素内に生成されます。詳細は、「WebサービスでのWS-Addressingの有効化(WSDLから始める場合)」を参照してください。

次の例では、WS-AddressingをJavaから有効にする方法を示します。この例では、エンドポイントでWS-Addressingが実行されます(requiredをtrueに設定)。

例2-3 WebサービスでのWS-Addressingの有効化(Javaから始める場合)

package examples;
import javax.jws.WebService;
import javax.xml.ws.soap.Addressing;

@WebService(name="HelloWorld", serviceName="HelloWorldService")
@Addressing(enabled=true, required=false)

public class HelloWorld {
public String sayHelloWorld(String message) throws MissingName { ... }
}

WebサービスでのWS-Addressingの有効化(WSDLから始める場合)

WebサービスでのWS-AddressingをWSDLから有効にするには、wsaw:UsingAddressing要素を対応するwsdl:binding要素に追加します。必要に応じて、wsdl:required Boolean属性を追加して、インバウンド・メッセージに対してWS-Addressingルールを適用するかどうかを指定できます。この属性のデフォルト値はfalseです。

次の例では、WS-AddressingをWSDLから有効にする方法を示します。この例では、エンドポイントでWS-Addressingが実行されます(wsdl:requiredをtrueに設定)。

例2-4 WebサービスでのWS-Addressingの有効化(WSDLから始める場合)

...
<binding name="HelloWorldPortBinding" type="tns:HelloWorld">
<wsaw:UsingAddressing wsdl:required="true" />
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document"/>
<operation name="sayHelloWorld">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
<fault name="MissingName">
<soap:fault name="MissingName" use="literal"/>
</fault>
</operation>
</binding>
...

Webサービス・クライアントでのWS-Addressingの有効化

WS-Addressingは、Webサービス・クライアントで暗黙的または明示的に有効にできます。クライアントで有効にすると、次のようになります。

- クライアントが受信したすべてのWS-Addressingヘッダーが認識されます。つまり、mustUnderstandを有効にしてWS-Addressingヘッダーを受信した場合、フォルトはスローされません。

- JAX-WSランタイムは次のことを行います。

- すべてのwsaw:Action要素(wsdl:operationのinput、outputおよびfault要素など)を、生成されたサービス・エンドポイント・インタフェース(SEI)のjavax.xml.ws.Actionおよびjavax.xml.ws.FaultActionアノテーションにマップします。

- アウトバウンド・リクエストにAction、To、MessageIDおよび匿名のReplyToヘッダーを生成します。

次の項では、Webサービス・クライアントでWS-Addressingを明示的および暗黙的に有効にする方法、およびWS-Addressingを明示的に無効にする方法について説明します。

- Webサービス・クライアントでのWS-Addressingの明示的な有効化

- Webサービス・クライアントでのWS-Addressingの暗黙的な有効化

- Webサービス・クライアントでのWS-Addressingの無効化

Webサービス・クライアントでのWS-Addressingの明示的な有効化

Webサービス・クライアントでは、javax.xml.ws.ServiceオブジェクトのgetPortまたはcreateDispatchメソッドにjavax.xml.ws.soap.AddressingFeatureを引数として渡すことにより、WS-Addressingを明示的に有効にできます。必要に応じて、表2-3に定義されているBooleanパラメータを1つ以上渡すことができます。

表2-3 AddressingFeature機能のパラメータ

パラメータ

説明

enabled

アウトバウンド・メッセージに対してWS-Addressingを有効にするかどうかを指定します。有効な値は、true(有効)およびfalse(無効)です。この属性のデフォルト値はtrueです。

required

インバウンド・メッセージに対してWS-Addressingルールを適用するかどうかを指定します。有効な値は、true(適用する)およびfalse(適用しない)です。falseに設定すると、WS-Addressingが有効かどうかを確認するためのチェックがインバウンド・メッセージに対して行われ、有効な場合はルールが適用されます。この属性のデフォルト値はfalseです。

次の例では、Webサービス・プロキシの作成時に、AddressingFeatureをgetPortメソッドに渡して、Webサービス・クライアントのWS-Addressingを有効にする方法を示します。

例2-5 Webサービス・プロキシのWebサービス・クライアントでのWS-Addressingの有効化

package examples.client;

import javax.xml.namespace.QName;
import java.net.MalformedURLException;
import java.net.URL;
import examples.client.MissingName_Exception;
import javax.xml.ws.soap.AddressingFeature;

public class Main {
public static void main(String[] args) throws MissingName_Exception {
HelloWorldService service;

try {
service = new HelloWorldService(new URL(args[0] + "?WSDL"),
new QName("http://examples/", "HelloWorldService") );
} catch (MalformedURLException murl) { throw new RuntimeException(murl); }

HelloWorld port = service.getHelloWorldPort(
new AddressingFeature(true, true));
...
}
}

次の例では、Dispatchインスタンスの作成時に、AddressingFeatureをcreateDispatchメソッドに渡してWebサービス・クライアントのWS-Addressingを有効にする方法を示します。

例2-6 DispatchインスタンスのWebサービス・クライアントでのWS-Addressingの有効化

...
HelloWorld port = service.getHelloWorldPort(new AddressingFeature(false));
...

Webサービス・クライアントでのWS-Addressingの暗黙的な有効化

wsaw:UsingAddressing拡張要素がWSDLに存在する場合、WS-Addressingは暗黙的に有効になります。詳細は、「WebサービスでのWS-Addressingの有効化(WSDLから始める場合)」を参照してください。

Webサービス・クライアントでのWS-Addressingの無効化

Webサービス・クライアントでは、独自のWS-Addressing処理モジュールを使用する場合など、WS-Addressing処理の明示的な無効化が必要となる場合があります。たとえば、MESSAGEモードのディスパッチ・クライアントを使用して非匿名のReplyToおよびFaultTo処理を実行する場合などです。

次の例では、Webサービス・プロキシの作成時に、Webサービス・クライアントのWS-Addressingを明示的に無効にする方法を示します。この例では、enabledをfalseに設定してAddressingFeature機能を呼び出します。

例2-7 Webサービス・クライアントでのWS-Addressingの無効化

...
new AddNumbersImplService().getAddNumbersImplPort(new javax.xml.ws.AddressingFeature(false));
...

WS-AddressingのActionプロパティの関連付け

WS-Addressingは属性wsaw:Actionを定義します。この属性を使用して、WebサービスにWS-AddressingのActionメッセージ・アドレッシング・プロパティを明示的に関連付けることができます。デフォルトでは、WS-Addressingが有効で、Webサービスに明示的に関連付けられているアクションがない場合は、暗黙的なアクションの関連付けが行われます。

次の項では、WS-AddressingのActionプロパティを明示的または暗黙的に関連付ける方法を説明します。

- WS-AddressingのActionプロパティの明示的な関連付け(Javaから始める場合)

- WS-AddressingのActionプロパティの明示的な関連付け(WSDLから始める場合)

- WS-AddressingのActionプロパティの暗黙的な関連付け

WS-AddressingのActionプロパティの明示的な関連付け(Javaから始める場合)

WS-AddressingのActionプロパティをJavaから明示的にWebサービスに関連付けるには、javax.xml.ws.Actionおよびjavax.xml.ws.FaultActionアノテーションを使用します。

必要に応じて、表2-4に定義されている属性を@Actionアノテーションに対して1つ以上渡すことができます。

表2-4 @Actionアノテーションの属性

属性

説明

input

操作のinputメッセージに対応するActionメッセージ・アドレッシング・プロパティを関連付けます。

output

操作のoutputメッセージに対応するActionメッセージ・アドレッシング・プロパティを関連付けます。

fault

操作のfaultメッセージに対応するActionメッセージ・アドレッシング・プロパティを関連付けます。表2-5に記載されているように、SOAP障害にマップされ、SOAPフォルトにマップし、明示的な関連付けが必要となる例外については、@FaultActionアノテーションを使用して指定する必要があります。

表2-4に定義されている属性を@FaultActionアノテーションに対して1つ以上渡すことができます。

表2-5 @FaultActionアノテーションの属性

属性

説明

className

例外クラスの名前。この属性は必須です。

value

例外のWS-Addressing Actionメッセージ・アドレッシング・プロパティの値。

WS-AddressingのActionプロパティを明示的に関連付けると、wsaw:Action属性が、wsdl:portType要素内の対応するinput要素、output要素およびfault要素に生成されます。詳細は、「WebサービスでのWS-Addressingの有効化(WSDLから始める場合)」を参照してください。

次の例では、@Actionおよび@FaultActionアノテーションを使用して、input、output、およびfaultメッセージに対応するWS-AddressingのActionメッセージ・アドレッシング・プロパティをsayHelloWorldに明示的に関連付ける方法を示します。

例2-8 アクションの明示的な関連付けの例(Javaから始める場合)

...
@Action(
input = "http://examples/HelloWorld/sayHelloWorldRequest",
output = "http://examples/HelloWorld/sayHelloWorldResponse",
fault = { @FaultAction(className = MissingName.class,
value = "http://examples/MissingNameFault")})

public String sayHelloWorld(String message) throws MissingName {
...

定義すると、エンドポイントのwsdl:operation要素内の対応するinput要素、output要素およびfault要素にwsaw:Action要素が生成されます。これらの要素の詳細は、「WS-Addressing Actionプロパティの明示的な関連付け(WSDLから始める場合)」を参照してください。

WS-AddressingのActionプロパティの明示的な関連付け(WSDLから始める場合)

WS-AddressingのActionプロパティをWSDLから明示的にWebサービスに関連付けるには、wwsaw:Action要素を対応するwsdl:binding要素に追加します。必要に応じて、wsdl:required Boolean属性を追加して、インバウンド・メッセージに対してWS-Addressingルールを適用するかどうかを指定できます。この属性のデフォルト値はfalseです。

次の例では、WSDLファイルで、HelloWorldエンドポイントのsayHelloWorldメソッドのinput、outputおよびfaultメッセージにWS-AddressingのActionメッセージ・アドレッシング・プロパティを明示的に関連付ける方法を示します。

例2-9 アクションの明示的な関連付けの例(WSDLから始める場合)

...
<portType name="HelloWorld">
<operation name="sayHelloWorld">
<input wsaw:Action="http://examples/HelloWorld/sayHelloWorldRequest"
message="tns:sayHelloWorld"/>
<output wsaw:Action="http://examples/HelloWorld/sayHelloWorldResponse"
message="tns:sayHelloWorldResponse"/>
<fault message="tns:MissingName" name="MissingName"
wsaw:Action="http://examples/MissingNameFault"/>
</operation>
</portType>
...

WS-AddressingのActionプロパティの暗黙的な関連付け

WS-Addressingが有効で、WSDLに明示的なアクションが定義されていない場合は、クライアントは次の形式を使用して暗黙的なwsa:Actionヘッダーを送信します。

- inputメッセージ・アクション: targetNamespace/portTypeName/inputName

- outputメッセージ・アクション: targetNamespace/portTypeName/outputName

- faultメッセージ・アクション: targetNamespace/portTypeName/operationName/Fault/FaultName

targetNamespace/portTypeName/[inputName | outputName]

たとえば、次のWSDLからの抜粋のようになります。

<definitions targetNamespace="http://examples/"...>
...
<portType name="HelloWorld">
<operation name="sayHelloWorld">
<input message="tns:sayHelloWorld" name="sayHelloRequest"/>
<output message="tns:sayHelloWorldResponse" name="sayHelloResponse"/>
<fault message="tns:MissingName" name="MissingName" />
</operation>
</portType>
...
</definitions>

デフォルトのinputおよびoutputアクションは次のように定義されます。

- inputメッセージ・アクション: http://examples/HelloWorld/sayHelloRequest

- outputメッセージ・アクション: http://examples/HelloWorld/sayHelloResponse

- faultメッセージ・アクション: http://examples/HelloWorld/sayHelloWorld/Fault/MissingName

WSDLでinputまたはoutputメッセージ名が指定されていない場合は、それぞれ操作名にRequestまたはResponseが追加された名前が使用されます。たとえば、sayHelloWorldRequestまたはsayHelloWorldResponseのようになります。

匿名WS-Addressingの構成

場合によって、ファイアウォールやDHCP(Dynamic Host Configuration Protocol)などのネットワーク・テクノロジが使用されている環境では、特定のエンドポイントに対してグローバルにアクセス可能なURIの使用が禁止されていることがあります。アドレッシングできないエンドポイントとのメッセージ交換を可能にするために、WS-Addressingの仕様ではwsaw:Anonymous要素を使用した「匿名」エンドポイントがサポートされています。

wsaw:Anonymous要素には表2-6に定義されているいずれかの値を設定できます。

表2-6 wsaw:Anonymous要素の有効な値

値

説明

optional

リクエスト・メッセージのレスポンス・エンドポイントEPRに匿名URIを含めることができます。

required

リクエスト・メッセージのレスポンス・エンドポイントEPRに匿名URLを含める必要があります。そうしないと、InvalidAddressingHeaderフォルトが返されます。

prohibited

リクエスト・メッセージのレスポンス・エンドポイントEPRに匿名URIを含めないでください。そうしないと、InvalidAddressingHeaderフォルトが返されます。

匿名WS-Addressingを構成するには:

1. WebサービスでWS-Addressingを有効にし、wsaw:UsingAddressing要素を対応するwsdl:binding要素に追加します。詳細は、「WebサービスでのWS-Addressingの有効化(WSDLから始める場合)」を参照してください。

注意:

匿名WS-Addressingが有効な場合は、wsaw:UsingAddressing要素でwsdl:required属性を有効にしないでください。

2. wsaw:Anonymous要素をwsdl:binding要素内のwsdl:operationに追加します。

次の例では、WSDLファイルで匿名WS-Addressingを有効にする方法を示します。この例では、匿名アドレッシングは必須です。

例2-10 Webサービスでの匿名WS-Addressingの有効化

...
<binding name="HelloWorldPortBinding" type="tns:HelloWorld">
<wsaw:UsingAddressing wsdl:required="true" />
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document"/>
<operation name="sayHelloWorld">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
<fault name="MissingName">
<soap:fault name="MissingName" use="literal"/>
</fault>
</operation>
<wsaw:Anonymous>required</wsaw:Anonymous>
</binding>
...

3 Webサービス・クライアントを開発する手順

この章では、Java API for XML Web Services(JAX-WS)用のWebLogic Webサービス・クライアントを開発するためのベスト・プラクティスについて説明します。

この章の内容は以下のとおりです。

- Webサービス・クライアントを開発する手順

- 非同期Webサービス・クライアントを開発する手順

注意:

『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebサービスの呼出しに関する項で説明されているWebサービス・クライアントの開発に関する一般的な概念に習熟していることが前提となっています。

信頼性のあるWebサービス・クライアントの開発に関するベスト・プラクティスについては、第5章「信頼性のあるWebサービスとクライアントを開発する手順」を参照してください。

次の項でクライアント・インスタンスは、ポートまたはディスパッチ・インスタンスです。

Webサービス・クライアントを開発する手順

表3-0では、Webサービス・クライアントを開発するためのベスト・プラクティスとその例を示します。非同期Webサービス・クライアントの開発に固有の他のベスト・プラクティスについては、「非同期Webサービス・クライアントを開発する手順」を参照してください。

表3-1 Webサービス・クライアントを開発する手順

ベスト・プラクティス

説明

クライアント・インスタンスの使用と同期させます。

クライアント・インスタンスは必要なときに作成します。長い間保存しないようにしてください。

クライアントIDを含む機能の保管されたリストを使用して、クライアント・インスタンスを作成します。

クライアントIDが含まれるWebサービス・クライアント・インスタンスのすべての機能を定義し、クライアント・インスタンスを作成するたびに異なることがないようにします。例:

_service.getBackendServicePort(_features);

クライアントIDを明示的に定義します。

ClientIdentityFeatureを使用してクライアントIDを明示的に定義します。このクライアントIDは、統計と他のモニタリング情報のグループ化や、実行時の検証のレポートに使用されます。詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のクライアントIDの管理に関する項を参照してください。

注意: クライアントIDは明示的に定義することを強くお薦めします。明示的に定義しないと、サーバーによって自動的にクライアントIDが生成されますが、ユーザーにとってわかりにくい場合があります。

処理が完了したら、クライアント・インスタンスを明示的に閉じます。

例:

((java.io.Closeable)port).close();

明示的に閉じないと、クライアント・インスタンスはユーザーがスコープ外になった時点で自動的に閉じられます。

注意: クライアントIDは、コンテナ(WebアプリケーションまたはEJB)が非アクティブ化されるまで、登録済みで可視の状態を維持します。詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のクライアントIDのライフサイクルに関する項を参照してください。

次の例では、Webサービス・クライアントを開発するためのベスト・プラクティスを示します。

例3-1 Webサービス・クライアントのベスト・プラクティスの例

import java.io.IOException;
import java.util.*;

import javax.servlet.*;
import javax.xml.ws.*;

import weblogic.jws.jaxws.client.ClientIdentityFeature;

/**
* Example client for invoking a Web service.
*/
public class BestPracticeClient
extends GenericServlet {

private BackendServiceService _service;
private WebServiceFeature[] _features;
private ClientIdentityFeature _clientIdFeature;

@Override
public void init()
throws ServletException {

// Create a single instance of a Web service as it is expensive to create repeatedly.
if (_service == null) {
_service = new BackendServiceService();
}

// Best Practice: Use a stored list of features, per client ID, to create client instances.
// Define all features for the Web service client instance, per client ID, so that they are
// consistent each time the client instance is created. For example:
// _service.getBackendServicePort(_features);

List<WebServiceFeature> features = new ArrayList<WebServiceFeature>();

// Best Practice: Explicitly define the client ID.
// TODO: Maybe allow ClientIdentityFeature to store other features, and
//       then create new client instances simply by passing the
//       ClientIdentityFeature (and the registered features are used).
_clientIdFeature = new ClientIdentityFeature("MyBackendServiceClient");
features.add(_clientIdFeature);

// Set the features used when creating clients with
// the client ID "MyBackendServiceClient". The features are stored in an array to
// reinforce that the list should be treated as immutable.
_features = features.toArray(new WebServiceFeature[features.size()]);
}

@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {

// ... Read the servlet request ...

// Best Practice: Synchronize use of client instances.
// Create a Web service client instance to talk to the backend service.
// Note, at this point the client ID is 'registered' and becomes
// visible to monitoring tools such as the Administration Console and WLST.
// The client ID *remains* registered and visible until the container
// (the Web application hosting our servlet) is deactivated (undeployed).
//
// A client ID can be used when creating multiple client instances (port or Dispatch client).
// The client instance should be created with the same set of features each time, and should
// use the same service class and refer to the same port type.
// A given a client ID should be used for a given port type, but not across port types.
// It can be used for both port and Dispatch clients.
BackendService port =
_service.getBackendServicePort(_features);

// Set the endpoint address for BackendService.
((BindingProvider)port).getRequestContext().
put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"http://localhost:7001/BestPracticeService/BackendService");

// Print out the explicit client ID, and compare it to the client ID
// that would have been generated automatically for the client instance.
showClientIdentity();

// Make the invocation on our real port
String request = "Make a cake";
System.out.println("Invoking DoSomething with request: " + request);
String response = port.doSomething(request);
System.out.println("Got response: " + response);
res.getWriter().write(response);

// Best Practice: Explicitly close client instances when processing is complete.
// If not closed, the client instance will be closed automatically when it goes out of
// scope. Note, this client ID will remain registered and visible until our
// container (Web application) is undeployed.
((java.io.Closeable)port).close();
}

/**
// Print out the client's full ID, which is a combination of
// the client ID provided above and qualifiers from the application and
// Web application that contain the client. Then compare this with the client ID that
// would have been generated for the client instance if not explicitly set.
//
private void showClientIdentity()
throws IOException {

System.out.println("Client Identity is: " + _clientIdFeature.getClientId());

// Create a client instance without explicitly defining the client ID to view the
// client ID that is generated automatically.
ClientIdentityFeature dummyClientIdFeature =
new ClientIdentityFeature(null);
BackendService dummyPort =
_service.getBackendServicePort(dummyClientIdFeature);
System.out.println("Generated Client Identity is: " +
dummyClientIdFeature.getClientId());
// Best Practice: Explicitly close client instances when processing is complete.
// If not closed, the client instance will be closed automatically when it goes out of
// scope. Note, this client ID will remain registered and visible until our
// container (Web application) is undeployed.
((java.io.Closeable)dummyPort).close();
}

@Override
public void destroy() {
}
}

非同期Webサービス・クライアントを開発する手順

表3-1では、非同期Webサービス・クライアントを開発するためのベスト・プラクティスとその例を示します。これらのガイドラインは、「Webサービス・クライアントを開発する手順」で示されている一般的なガイドラインと併せて使用する必要があります。

表3-2 非同期Webサービス・クライアントを開発する手順

ベスト・プラクティス

説明

非同期およびディスパッチ・コールバック処理のためにポートベースの非同期コールバック・ハンドラAsyncClientHandlerFeatureを定義します。

拡張性があり、JVMを再起動しても維持されるため、非同期呼び出しを使用するときのベスト・プラクティスとして、AsyncClientHandlerFeatureを使用することをお薦めします。このハンドラは(持続可能かどうかに関係なく)任意のクライアントで使用できます。詳細は、「非同期ハンドラ・インタフェースの開発」を参照してください。

シングルトン・ポート・インスタンスを定義し、(デプロイメント時に)クライアント・コンテナを初期化するときに初期化します。

シングルトン・ポートの作成:

- デプロイメント時に公開する非同期レスポンス・エンドポイントをトリガーします。

- VMの再起動後にシングルトン・ポート・インスタンスを再初期化することで、障害リカバリをサポートします。

クラスタ内では、シングルトン・ポートを初期化すると、クラスタ内のすべてのメンバー・サーバーが非同期レスポンス・エンドポイントをパブリッシュすることが保証されます。これによって、非同期レスポンス・メッセージが任意のメンバー・サーバーに配信され、必要に応じてインプレース・クラスタ・ルーティングを介して正しいサーバーに転送されることが保証されます。詳細は、「非同期Webサービス・メッセージングのクラスタリングの考慮事項」を参照してください。

ファイアウォールの内側にあるクライアントに接続作成を使用する場合は、接続作成ポーリング間隔をシナリオに対して現実的な値に設定します。

接続作成のポーリング間隔は、不必要なポーリング・オーバーヘッドを避けることができる大きな値で、なおかつ遅れずにレスポンスを取得できる十分に小さい値に設定する必要があります。接続作成ポーリング間隔の推奨される値は、呼び出されるWebサービスの予想される平均レスポンス時間の半分です。接続作成ポーリング間隔の設定の詳細は、「ポーリング間隔の構成」を参照してください。

注意: このベスト・プラクティスは、例3-2では示されていません。

JAX-WS参照実装(RI)を使用している場合は、AsyncHandler<T>インタフェースを実装します。

AsyncHandler<T>インタフェースを使用する方が、Response<T>インタフェースを使用するより効率的です。詳細および例は、「JAX-WS参照実装の使用」を参照してください。

注意: このベスト・プラクティスは、例3-2では示されていません。

ワーク・マネージャを定義し、スレッド・プールの最小サイズ制限(min-threads-constraint)を、最低でもサービスに対して予想される同時リクエスト数または同時レスポンス数と同じ値に設定します。

たとえば、Webサービス・クライアントが20個のリクエストを立て続けに発行する場合、そのクライアントをホストするアプリケーションで推奨されるスレッド・プールの最小サイズ制約の値は20です。構成した制約値が小さすぎると、受信処理で処理スレッドの空き待ちが発生するためパフォーマンスが大幅に低下するおそれがあります。

スレッド・プールの最小サイズ制約の詳細は、『Oracle WebLogic Serverサーバー環境の構成』の制約に関する項を参照してください。

次の例では、非同期Webサービス・クライアントを開発するためのベスト・プラクティスを示します。

例3-2 非同期Webサービス・クライアントのベスト・プラクティスの例

import java.io.*;
import java.util.*;

import javax.servlet.*
import javax.xml.ws.*

import weblogic.jws.jaxws.client.ClientIdentityFeature;
import weblogic.jws.jaxws.client.async.AsyncClientHandlerFeature;
import weblogic.jws.jaxws.client.async.AsyncClientTransportFeature;

import com.sun.xml.ws.developer.JAXWSProperties;

/**
* Example client for invoking a Web service asynchronously.
*/
public class BestPracticeAsyncClient
extends GenericServlet {

private static final String MY_PROPERTY = "MyProperty";

private BackendServiceService _service;
private WebServiceFeature[] _features;
private BackendService _singletonPort;

private static String _lastResponse;
private static int _requestCount;

@Override
public void init()
throws ServletException {

// Only create the Web service object once as it is expensive to create repeatedly.
if (_service == null) {
_service = new BackendServiceService();
}

// Best Practice: Use a stored list of features, including client ID, to create client
// instances.
// Define all features for the Web service client instance, including client ID, so that they
// are consistent each time the client instance is created. For example:
// _service.getBackendServicePort(_features);

List<WebServiceFeature> features = new ArrayList<WebServiceFeature>();

// Best Practice: Explicitly define the client ID.
ClientIdentityFeature clientIdFeature =
new ClientIdentityFeature("MyBackendServiceAsyncClient");
features.add(clientIdFeature);

// Asynchronous endpoint
AsyncClientTransportFeature asyncFeature =
new AsyncClientTransportFeature(getServletContext());
features.add(asyncFeature);

// Best Practice: Define a port-based asynchronous callback handler,
// AsyncClientHandlerFeature, for asynchronous and dispatch callback handling.
BackendServiceAsyncHandler handler =
new BackendServiceAsyncHandler() {
// This class is stateless and should not depend on
// having member variables to work with across restarts.
public void onDoSomethingResponse(Response<DoSomethingResponse> res) {
// ... Handle Response ...
try {
DoSomethingResponse response = res.get();
res.getContext();
_lastResponse = response.getReturn();
System.out.println("Got async response: " + _lastResponse);
// Retrieve the request property. This property can be used to
// 'remember' the context of the request and subsequently process
// the response.
Map<String, Serializable> requestProps =
(Map<String, Serializable>)
res.getContext().get(JAXWSProperties.PERSISTENT_CONTEXT);
String myProperty = (String)requestProps.get(MY_PROPERTY);
System.out.println("Got MyProperty value propagated from request: "+
myProperty);
} catch (Exception e) {
_lastResponse = e.toString();
e.printStackTrace();
}
}
};
AsyncClientHandlerFeature handlerFeature =
new AsyncClientHandlerFeature(handler);
features.add(handlerFeature);

// Set the features used when creating clients with
// the client ID "MyBackendServiceAsyncClient".

_features = features.toArray(new WebServiceFeature[features.size()]);

// Best Practice: Define a singleton port instance and initialize it when
// the client container initializes (upon deployment).
// The singleton port will be available for the life of the servlet.
// Creation of the singleton port triggers the asynchronous response endpoint to be published
// and it will remain published until our container (Web application) is undeployed.
// Note, the destroy() method will be called before this.
// The singleton port ensures proper/robust operation in both
// recovery and clustered scenarios.
_singletonPort = _service.getBackendServicePort(_features);
}

@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {

// TODO: ... Read the servlet request ...

// For this simple example, echo the _lastResponse captured from
// an asynchronous DoSomethingResponse response message.

if (_lastResponse != null) {
res.getWriter().write(_lastResponse);
_lastResponse = null; // Clear the response so we can get another
return;
}

// Set _lastResponse to NULL to to support the invocation against
// BackendService to generate a new response.

// Best Practice: Synchronize use of client instances.
// Create another client instance using the *exact* same features used when creating _
// singletonPort. Note, this port uses the same client ID as the singleton port
// and it is effectively the same as the singleton
// from the perspective of the Web services runtime.
// This port will use the asynchronous response endpoint for the client ID,
// as it is defined in the _features list.
BackendService anotherPort =
_service.getBackendServicePort(_features);

// Set the endpoint address for BackendService.
((BindingProvider)anotherPort).getRequestContext().
put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"http://localhost:7001/BestPracticeService/BackendService");

// Add a persistent context property that will be retrieved on the
// response. This property can be used as a reminder of the context of this
// request and subsequently process the response. This property will *not*
// be passed over the wire, so the properties can change independent of the
// application message.
Map<String, Serializable> persistentContext =
(Map<String, Serializable>)((BindingProvider)anotherPort).
getRequestContext().get(JAXWSProperties.PERSISTENT_CONTEXT);
String myProperty = "Request " + (++_requestCount);
persistentContext.put(MY_PROPERTY, myProperty);
System.out.println("Request being made with MyProperty value: " +
myProperty);

// Make the asychronous invocation. The asynchronous handler implementation (set
// into the AsyncClientHandlerFeature above) receives the response.
String request = "Dance and sing";
System.out.println("Invoking DoSomething asynchronously with request: " +
request);
anotherPort.doSomethingAsync(request);

// Return a canned string indicating the response was not received
// synchronously. Client will need to invoke the servlet again to get
// the response.
res.getWriter().write("Waiting for response...");

// Best Practice: Explicitly close client instances when processing is complete.
// If not closed explicitly, the port will be closed automatically when it goes out of scope.
((java.io.Closeable)anotherPort).close();
}

@Override
public void destroy() {

try {
// Best Practice: Explicitly close client instances when processing is complete.
// Close the singleton port created during initialization. Note, the asynchronous
// response endpoint generated by creating _singletonPort *remains*
// published until our container (Web application) is undeployed.
((java.io.Closeable)_singletonPort).close();

// Upon return, the Web application is undeployed, and the asynchronous
// response endpoint is stopped (unpublished). At this point,
// the client ID used for _singletonPort will be unregistered and will no longer be
// visible from the Administration Console and WLST.
} catch (Exception e) {
e.printStackTrace();
}
}
}

4 Webサービスの非同期呼出し

この章では、Java API for XML Web Services(JAX-WS)を使用したWebLogic Webサービスを非同期に呼び出す方法について説明します。

この章の内容は以下のとおりです。

- Webサービスの非同期呼出しの概要

- Webサービスを非同期に呼び出す手順

- Webサービスを非同期に呼び出すためのサーバーの構成

- Webサービスを非同期に呼び出すためのクライアント・アーティファクトの構築

- スケーラブルな非同期JAX-WSクライアントの開発(非同期クライアント・トランスポート)

- ファイアウォールの内側からの非同期Webサービス・クライアントの使用(接続作成)

- JAX-WS参照実装の使用

- レスポンスへのリクエスト・コンテキストの伝播

- 非同期Webサービス呼出しのモニタリング

- 非同期Webサービス・メッセージングのクラスタリングの考慮事項

注意:

「Webサービス・クライアントを開発する手順」も参照してください。

Webサービスの非同期呼出しの概要

Webサービスの非同期呼出しをサポートするため、WebLogic Webサービスでは、非同期クライアント・プログラミング・モデルと非同期トランスポートのどちらか一方または両方を使用できます。

表4-1では、非同期クライアント・プログラミング・モデルの主要な利点とトランスポート・タイプ、およびWebサービスの非同期呼出しをサポートするために使用できる構成オプションについて説明します。

注意:

2つのportType(非同期操作用に1つとコールバック操作用に1つ)として定義される2つの一方向操作を含む非同期Webサービス用のWSDLを生成する方法は、現在のリリースではサポートされていません。

表4-1 非同期Webサービス呼出しのサポート

タイプ

説明

利点

クライアント・プログラミング・モデル

Webサービス操作の呼出しに使用される呼出しセマンティクスを記述します(同期または非同期)。

Webサービスを同期的に呼び出す場合、呼出し側のクライアント・アプリケーションは、レスポンスが戻るまで待機してから、処理を続行します。レスポンスが即座に戻る場合であれば、このWebサービス呼出しの方法は適切であると考えられます。しかし、リクエストの処理が遅延する可能性があるため、クライアント・アプリケーションによる処理を続行しレスポンスへの対処は後で行うようにすると便利なことがよくあります。

Webサービスを非同期的に呼び出すと、クライアントは処理を中断することなく続行でき、非同期レスポンスが返ると通知を受け取ります。

非同期呼出しをサポートするには、clientgen Antタスクを使用して、Webサービス・ポート上で非同期的な種類の操作をそれぞれ自動的に生成します(この後の「非同期Webサービス呼出しのためのクライアント・アーティファクトの作成」で説明しています)。続いて、非同期のレスポンスまたは障害が後で戻されたときにそれを処理するクライアントのメソッド(ビジネス・ロジックを含む)を追加します。最後に、Webサービスを非同期的に呼び出すため、操作を直接呼び出すのではなく、非同期的な種類の操作を呼び出します。たとえば、addNumbersという操作を直接呼び出すのではなく、addNumbersAsyncを呼び出します。

非同期的に呼び出すことで、Webサービス・クライアントは、Webサービスに対するリクエストを開始し、中断することなく処理を続行し、以降の何らかの時点でレスポンスを受け取ることができます。

トランスポート

トランスポートには、非同期クライアント・トランスポート、接続作成トランスポート、同期トランスポートの3種類があります。トランスポートの各タイプの比較については、表4-2を参照してください。

非同期クライアント・トランスポートおよび接続作成トランスポートの主要な利点は次のとおりです。

- ネットワークが停止したときのフォルト・トレランスが向上します。

- サーバーでトラフィックのスパイクをいっそう効果的に緩和できるようになります。

構成

Webサービスの非同期呼出しをサポートするようにWebサービスの永続性とバッファリング(オプション)を構成します。

詳細は、「Webサービスを非同期に呼び出すためのサーバーの構成」を参照してください。

Webサービス機能の構成には、次のような利点があります。

- 永続性は、時間のかかるリクエストをサポートし、途中でサーバーを再起動しても継続できます。

- バッファリングを使用すると、Webサービスに対するすべてのリクエストを非同期に処理できます。

表4-2では、Webサービス・クライアントからのWebサービスの非同期呼出し(または、構成されている場合は同期呼出し)に対してWebLogic Serverがサポートするトランスポートのタイプを示します。

表4-2 Webサービスの非同期呼出しのトランスポート・タイプ

トランスポート・タイプ

説明

非同期クライアント・トランスポート

アドレス可能なクライアント側非同期レスポンス・エンドポイントとWS-Addressingを使用することで、スケーラブルな非同期クライアント・プログラミング・モデルを提供します。

非同期クライアント・トランスポートは、レスポンス・メッセージの配信を、リクエスト・メッセージの送信に使用されるトランスポート・リクエストの開始から切り離します。レスポンス・メッセージは、Webサービスから開始する新しい接続を使用して、非同期レスポンス・エンドポイントに送信されます。クライアントは、WS-Addressingヘッダーを使用して、リクエスト・メッセージとレスポンス・メッセージを関連付けます。

非同期クライアント・トランスポートは、向上したフォルト・トレランスを提供し、サーバー負荷のスパイクをより適切に緩和できるようにします。

非同期クライアント・トランスポートの使用に関する詳細は、「スケーラブルな非同期JAX-WSクライアントの開発(非同期クライアント・トランスポート)」を参照してください。

非同期クライアント・トランスポートは、次のプログラミング・モデルをサポートします。

- 次のいずれかの方法を使用する非同期およびディスパッチ・コールバック処理。
- 「非同期ハンドラ・インタフェースの開発」で説明されているポートベースの非同期コールバック・ハンドラAsyncClientHandlerFeature。拡張性があり、JVMを再起動しても維持されるため、非同期呼び出しを使用するときのベスト・プラクティスとして使用することをお薦めします。

- 「JAX-WS参照実装の使用」で説明されている、リクエストごとの非同期コールバック・ハンドラ。

- 「JAX-WS参照実装の使用」で説明されている非同期ポーリング。

- 「同期操作のための非同期クライアント・トランスポートの構成」で説明されている、フラグの有効化による同期呼出し。

接続作成トランスポート

Web Services Make Connection 1.1または1.0を使用してファイアウォールの内側からの非同期Webサービス呼出しを可能にします。

接続作成は、非同期クライアント・トランスポートの代わりとなるクライアント・ポーリング・メカニズムです。非同期クライアント・トランスポートと同様に、接続作成を使用するとリクエスト・メッセージの送信に使用されるトランスポート・リクエストの開始から、レスポンス・メッセージを切り離すことができます。ただし、レスポンスを転送するためにアドレス可能な非同期レスポンス・エンドポイントを必要とする非同期クライアント・トランスポートとは異なり、接続作成では、通常、リクエスト・メッセージの送信元はアドレス可能ではなく、着信接続を受け付けることはできません。たとえば、送信元がファイアウォールの内側にあるような場合です。

接続作成トランスポートは、向上したフォルト・トレランスを提供し、サーバー負荷のスパイクをより適切に緩和できるようにします。

接続作成トランスポートの詳細は、「ファイアウォールの内側からの非同期Webサービス・クライアントの使用(接続作成)」を参照してください。

接続作成トランスポートは拡張性があり、JVMを再起動しても維持されるため、ファイアウォールの内側から非同期呼出しを使用するときのベスト・プラクティスとしてお薦めします。次のプログラミング・モデルをサポートします。

- 次のいずれかの方法を使用する非同期およびディスパッチ・コールバック処理。
- 「非同期ハンドラ・インタフェースの開発」で説明されているポートベースの非同期コールバック・ハンドラAsyncClientHandlerFeature。

- 「JAX-WS参照実装の使用」で説明されている、リクエストごとの非同期コールバック・ハンドラ。

- 「JAX-WS参照実装の使用」で説明されている非同期ポーリング。

- 「同期メソッドのトランスポートとしての接続作成の構成」で説明されている、フラグの有効化による同期呼出し。

拡張性があり、JVMを再起動しても維持されるため、非同期呼出しを使用するときのベスト・プラクティスとして、接続作成トランスポートとAsyncClientHandlerFeatureを使用することをお薦めします。

同期トランスポート

WS-Addressingの非常に制限されたサポートで、同期と非同期のWebサービス呼出しをサポートします。詳細は、「JAX-WS参照実装の使用」を参照してください。

同期呼出しを使用するときは、同期トランスポートをお薦めします。ベスト・プラクティスとはみなされませんが、非同期呼出しに使用することもできます。次のプログラミング・モデルをサポートします。

- 「JAX-WS参照実装の使用」で説明されている、標準JAX-WS RIの実装を使用したリクエスト単位での非同期およびディスパッチ・コールバック処理。

- 「JAX-WS参照実装の使用」で説明されている非同期ポーリング。

- 同期呼出し。

非同期でWebサービスを呼び出すための手順

この項では、Webサービスを非同期に呼び出すために必要な手順について説明します。

Antベースの開発環境を設定済であり、かつjwsc Antタスクを実行してWebサービスをデプロイするためのターゲットを追加できる、作業用のbuild.xmlファイルがあることが前提となっています。詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』を参照してください。

表4-3 非同期でWebサービスを呼び出すための手順

#

手順

説明

1

Webサービスの非同期呼出しをサポートするようにWebサービスの永続性を構成します。

Webサービスまたはクライアントでメッセージを処理するために必要なコンテキスト情報を保持するように、WebサービスとクライアントをホストするサーバーでWebサービスの永続性を構成します。詳細は、「非同期Webサービス呼出しのためのサーバーの構成」を参照してください。

注意: 「JAX-WS参照実装の使用」で説明されているように、(手順3で)標準のJAX-WS RI実装と同期トランスポートを使用してWebサービス・クライアントをプログラミングしている場合は、この手順は必要ありません。

2

Webサービス・バッファリングを構成して、リクエストを非同期的に処理するためのWebサービスを有効化します。(オプション)

この手順はオプションです。リクエストを非同期に処理するようにWebサービスを構成するには、Webサービスをホストするサーバーでバッファリングを構成します。バッファリングを使用すると、Webサービスによる非同期処理のためにJMSキューにメッセージを格納できます。詳細は、「非同期Webサービス呼出しのためのサーバーの構成」を参照してください。

3

非同期呼出しに必要なクライアント・アーティファクトを作成します。

サービス・エンドポイント・インタフェースで非同期ポーリング・メソッドおよび非同期コールバック・ハンドラ・メソッドを生成するには、非同期マッピングを可能にする外部バインディング宣言を作成し、クライアントをコンパイルするときにclientgenに引数としてバインディング・ファイルを渡します。「非同期Webサービス呼出しのためのクライアント・アーティファクトの作成」を参照してください。

4

必要なトランスポートとプログラミング・モデルに基づいて、Webサービス・クライアントを実装します。

必要なトランスポートとプログラミング・モデルに応じて、次のいずれかの項を参照してください。

- 非同期クライアント・トランスポート機能を使用します(「スケーラブルな非同期JAX-WSクライアントの開発(非同期クライアント・トランスポート)」)を参照)。(ベスト・プラクティスとして推奨)

- 接続作成を使用してファイアウォールの内側からの非同期アクセスを可能にします。「ファイアウォールの内側からの非同期Webサービス・クライアントの使用(接続作成)」を参照してください。

- 同期トランスポートを使用して、非同期ポーリングやリクエストごとの非同期コールバック処理などの標準JAX-WSプログラミング・モデルを実装します。「JAX-WS参照実装の使用」を参照してください。

クラスタでWebサービスを使用するときは、「非同期Webサービス・メッセージングのクラスタリングに関する考慮事項」で説明されているガイドラインを確認してください。

5

Webサービス・クライアントをコンパイルし、クライアント・アーティファクトのパッケージを作成します。

詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のクライアント・アプリケーションのコンパイルと実行に関する項を参照してください。

6

Webサービス・クライアントをデプロイします。

『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebLogic Webサービスのデプロイとアンデプロイに関する項を参照してください。

7

Webサービス・クライアントをモニターします。

管理コンソールまたはWLSTを使用して、呼出し、エラー、フォルトの数など、Webサービスを非同期に呼び出すクライアントの実行時情報をモニターできます。「非同期Webサービス呼出しのモニタリング」を参照してください。

Webサービスを非同期に呼び出すためのサーバーの構成

注意:

「JAX-WS参照実装の使用」で説明されているように、標準のJAX-WS RI実装と同期トランスポートを使用してWebサービス・クライアントをプログラミングしている場合は、この手順は必要ありません。

Webサービスの非同期呼出しをサポートするには、Webサービスとクライアントをデプロイするサーバーで、次の表で定義されている機能を構成する必要があります。

表4-4 非同期Webサービス呼出しの構成

機能

説明

永続性

Webサービスの永続性は、次の種類の情報を保存するために使用されます。

- クライアントのIDとプロパティ

- ヘッダーと本体を含むSOAPメッセージ

- Webサービスまたはクライアントでメッセージを処理するために必要なコンテキスト・プロパティ(非同期メッセージと同期メッセージの両方)

接続作成トランスポート・プロトコルは、Webサービスの永続性を次のように利用します。

- MCレシーバ(Webサービス)上に構成されたWebサービス永続性は、宛先の接続作成匿名URIに対する着信接続作成メッセージを待機しているレスポンス・メッセージを保持します。メッセージは、着信接続作成メッセージに対するレスポンスとして返されるまで、または永続ストア・オブジェクトの最大存続期間に達してストアから消去されるまで保持されます。

- MCイニシエータ(Webサービス・クライアント)上に構成されたWebサービス永続性は、VM再起動後のリカバリのために非同期クライアント・ハンドラ機能で使用されます。

構成ウィザードでWebサービス固有の拡張テンプレートを使用してWebLogic Serverドメインを拡張することにより、Webサービスの永続性を構成できます。あるいは、Oracle WebLogic管理コンソールまたはWLSTを使用して、これらの高度な機能に必要なリソースを構成できます。Webサービス永続性の構成の詳細は、「Webサービス・クライアントのためのWebサービス永続性の構成」を参照してください。クライアントとメッセージの情報の保持に使用できるAPIの詳細は、「レスポンスへのリクエスト・コンテキストの伝播」を参照してください。

メッセージ・バッファリング

バッファ付き操作がクライアントによって呼び出されると、リクエストはJMSキューに格納され、WebLogic Serverはリクエストを非同期に処理します。リクエストがまだキューの中にある間にWebLogic Serverがダウンした場合は、WebLogic Serverが再起動してからすぐにリクエストの処理が行われます。メッセージ・バッファリングは、Webサービスをホストしているサーバー上で構成されます。構成情報の詳細は、第8章「Webサービスのためのメッセージ・バッファリングの構成」を参照してください。

注意: Webサービス・クライアントではメッセージ・バッファリングが自動的に有効になります。

Webサービスを非同期に呼び出すためのクライアント・アーティファクトの構築

WebLogic Serverのクライアント側ツール(clientgenなど)を使用すると、非同期Webサービス呼出しに必要なクライアント・アーティファクトを自動的に生成できます。具体的には、次のアーティファクトが生成されます。

- リクエストごとの非同期コールバック・ハンドラを使用して、または使用しないで、Webサービスを非同期に呼び出すためのサービス・エンドポイント・インタフェース。たとえば、Webサービスで次のようなメソッドが定義されているものとします。

public int addNumbers(int opA, int opB) throws MyException

この場合は、次のようなメソッドが生成されます。

public Future<?> addNumbersAsync(int opA, int opB,
AsyncHandler<AddNumbersResponse>)
public Response<AddNumbersResponse> addNumbersAsync(int opA, int opB)

- ハンドラを実装し、AsyncClientHandlerFeatureを使用してポート上にそのハンドラを設定するための非同期ハンドラ・インタフェース。非同期ハンドラ・インタフェースの名前は、portInterfaceNameAsyncHandlerとなり、ここでportInterfaceNameはポート・インタフェース名を指定します。
たとえば、ポート・タイプ名がAddNumbersPortTypeであるWebサービスの場合、次のメソッドを含むAddNumbersPortTypeAsyncHandlerという名前の非同期ハンドラ・インタフェースが生成されます。

public void onAddNumbersResponse(Response<AddNumbersResponse>)

AsyncClientHandlerFeatureについては、後の「非同期ハンドラ・インタフェースの開発」で説明します。

WSDLのコンパイル時に、サービス・エンドポイント・インタフェースで非同期クライアント・アーティファクトを生成するには、WSDLファイルでjaxws:enableAsyncMappingバインディング宣言を有効にします。

あるいは、特定のWSDLまたはXMLスキーマ・ドキュメントのすべてのバインディング宣言を格納する外部バインディング宣言ファイルを作成できます。次に、バインディング宣言ファイルをwsdlc、jwsc、またはclientgen Antタスクの<binding子要素に渡します。詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のJAX-WSバインディング宣言を使用した外部バインディング宣言ファイルの作成に関する項を参照してください。

次に示すバインディング宣言ファイル(jaxws-binding.xml)の例では、jaxws:enableAsyncMappingバインディング宣言を有効にしています。

<bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
wsdlLocation="AddNumbers.wsdl"
xmlns="http://java.sun.com/xml/ns/jaxws">
<bindings node="wsdl:definitions">
<package name="examples.webservices.async"/>
<enableAsyncMapping>true</enableAsyncMapping>
</bindings>
</bindings>

次に、build.xmlファイルを更新し、Webサービス操作を非同期に呼び出すために必要なクライアント・アーティファクトを生成するため、次の手順を実行します。

1. taskdef Antタスクを使用して、clientgen Antタスクの完全なクラス名を定義します。

2. 前に定義した非同期バインディング宣言が格納されている外部バインディング宣言ファイルへの参照を含むターゲットを追加します。この場合、clientgen Antタスクは、同期的な種類と非同期的な種類のWebサービス操作をJAX-WSスタブ内に生成します。

例:

<taskdef name="clientgen"
classname="weblogic.wsee.tools.anttasks.ClientGenTask" />

<target name="build_client">

<clientgen
type="JAXWS"
wsdl="AddNumbers.wsdl"
destDir="${clientclasses.dir}"
packageName="examples.webservices.async.client">
<binding file="jaxws-binding.xml" />
</clientgen>
<javac
srcdir="${clientclass-dir}" destdir="${clientclass-dir}"
includes="**/*.java"/>
<javac
srcdir="src" destdir="${clientclass-dir}"
includes="examples/webservices/async/client/**/*.java"/>

</target>

スケーラブルな非同期JAX-WSクライアントの開発(非同期クライアント・トランスポート)

非同期クライアント・トランスポート機能は、スケーラブルな非同期クライアント・プログラミング・モデルを提供します。具体的には、次のような機能があります。

- 図4-1に示すような、クライアント側の非同期レスポンス・エンドポイントを公開します。

- 要求された非同期ハンドラの実装を呼び出すサービスの実装を作成して公開します。

- すべての非一方向アウトバウンド・メッセージに、WS-Addressingの非匿名ReplyToヘッダーを自動的に追加します。このヘッダーは、公開されたレスポンス・エンドポイントを参照します。

- 前記の機能を使用して、非同期リクエストとレスポンス・メッセージを関連付けます。

非同期クライアント・トランスポート機能が有効になっているとき、他のすべてのJAX-WSクライアント・プログラミング・モデル(非同期ポーリング、コールバック・ハンドラ、ディスパッチなど)は引き続きサポートされます。非同期クライアント・トランスポート機能が有効になっているとき、この機能を使用するように明示的に構成されていないと、同期Webサービス操作はデフォルトで同期トランスポートを使用します。

次の図では、非同期クライアント・トランスポート機能が使用するメッセージ・フローを示します。

図4-1 非同期クライアント・トランスポート機能

「図4-1 非同期クライアント・トランスポート機能」の説明

前の図に示すように、次のような処理が行われます。

1. クライアントは、クライアント・プロキシで非同期クライアント・トランスポート機能を有効にして、非同期Webサービス操作を呼び出します。

2. Webサービス操作がクライアント・プロキシを介して呼び出されます。

3. Webサービスはリクエストを処理し、(その後のどこかの時点で)レスポンス・メッセージをクライアントに返送します。レスポンス・メッセージはクライアントの非同期レスポンス・エンドポイントに送信されます。非同期レスポンス・エンドポイントのアドレスは、WS-Addressingヘッダーに保持されています。

4. レスポンス・メッセージがクライアント・プロキシを介して適切なクライアントに転送されます。

5. レスポンス・メッセージを処理するために、クライアントの非同期ハンドラが呼び出されます。

次の項では、非同期クライアント・トランスポートを使用してスケーラブルな非同期JAX-WSクライアントを開発する方法を説明します。

- 非同期クライアント・トランスポート機能の有効化と構成

- 非同期ハンドラ・インタフェースの開発

- レスポンスへのユーザー定義リクエスト・コンテキストの伝播

非同期クライアント・トランスポート機能の有効化と構成

注意:

接続作成と非同期クライアント・トランスポート機能を一緒に使用することはできません。同じWebサービス・クライアントで両方の機能を有効にしようとすると、エラーが返されます。接続作成の詳細は、「ファイアウォールの内側からの非同期Webサービス・クライアントの使用(接続作成)」を参照してください。

クライアントで非同期クライアント・トランスポート機能を有効にするには、Webサービス・プロキシまたはディスパッチを作成するときにパラメータとしてweblogic.jws.jaxws.client.async.AsyncClientTransportFeatureのインスタンスを渡します。次の項では、クライアントで非同期クライアント・トランスポート機能を有効にして構成する方法を説明します。

- 非同期レスポンス・エンドポイントのアドレスの構成

- 非同期レスポンス・エンドポイントのReplyToヘッダーとFaultToヘッダーの構成

- 非同期レスポンス・エンドポイントのコンテキスト・パスの構成

- 非同期レスポンス・エンドポイントの公開

- 同期操作用の非同期クライアント・トランスポートの構成

AsyncClientTransportFeatureによって記述されている非同期レスポンス・エンドポイントは、同じクライアントIDを共有するすべてのクライアント・インスタンスによって使用され、そのクライアントIDを使用する最初のクライアント・インスタンスが公開された時点から有効になります。非同期レスポンス・エンドポイントは、クライアントIDが明示的に破棄されるか、または(たとえば、ホストWebアプリケーションまたはEJBがアンデプロイされて)クライアントのコンテナが非アクティブ化されるまで、発行されたままになります。クライアントIDの管理の詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のクライアントIDの管理に関する項を参照してください。

非同期レスポンス・エンドポイント・アドレスは、次の形式を使用して自動的に生成されます。

http://contextAddress:port/context/targetPort-AsyncResponse

各値の説明は次のとおりです。

- contextAddress:port: 次のいずれかを指定します。

- クラスタ・アプリケーションの場合は、クラスタ・アドレスとポート。

- クラスタ・アプリケーションでない場合は、選択されているプロトコルのデフォルトのWebLogic Serverアドレスとポート。

- デフォルトのアドレスが定義されていない場合は、指定されているプロトコルの最初のネットワーク・チャネル・アドレス。ネットワーク・チャネルの詳細は、『Oracle WebLogic Serverサーバー環境の構成』のネットワーク・リソースの構成に関する項を参照してください。

- context: 既存のコンテキスト内で実行している場合は、現在のサーブレット・コンテキスト。それ以外の場合は、UUIDによって名前を指定され、スコープがアプリケーションに設定された、新しいコンテキスト。

- targetPort-AsyncResponse: クライアントによってアクセスされるサービスのポート名の後に-AsyncResponseを付加したもの。

非同期クライアント・トランスポート機能は、次の項で説明するように構成できます。

- 非同期レスポンス・エンドポイントのアドレスの構成

- 非同期レスポンス・エンドポイントのReplyToヘッダーとFaultToヘッダーの構成

- 非同期レスポンス・エンドポイントのコンテキスト・パスの構成

- 非同期レスポンス・エンドポイントの公開

- 同期操作用の非同期クライアント・トランスポートの構成

AsyncClientTransportFeature()コンストラクタの形式の詳細は、WebLogic Server Javadocを参照してください。

非同期レスポンス・エンドポイントのアドレスの構成

次に示すように、非同期レスポンス・エンドポイントのアドレスは、AsyncClientTransportFeatureに引数として渡すことで構成できます。

String responseAddress = "http://myserver.com:7001/myReliableService/myClientCallback";
AsyncClientTransportFeature asyncFeature = new AsyncClientTransportFeature(responseAddress);
BackendService port = _service.getBackendServicePort(asyncFeature);

指定アドレスは、サーバーまたはクラスタの合法的なアドレスにする必要があります(ネットワーク・チャネルまたはプロキシ・アドレスを含む)。エフェメラル・ポートはサポートされません。指定するコンテキストは、スコープを現在のアプリケーション内に指定されているか、または未使用コンテキストを参照している必要があります。別のデプロイ済アプリケーションにスコープが設定されているコンテキストは参照できません。参照しようとするとエラーがスローされます。

次の表では、非同期レスポンス・エンドポイントのアドレスの構成に使用できるコンストラクタを示します。

表4-5 非同期レスポンス・エンドポイントのアドレスを構成するためのコンストラクタ

コンストラクタ

説明

AsyncClientTransportFeature(java.lang.String address)

非同期レスポンス・エンドポイントのアドレスを構成します。

AsyncClientTransportFeature(java.lang.String address, boolean doPublish)

次のものを構成します。

- 非同期レスポンス・エンドポイントのアドレス。

- 指定したアドレスでエンドポイントを公開するかどうか。詳細は、「非同期レスポンス・エンドポイントの公開」を参照してください。

AsyncClientTransportFeature(java.lang.String address, boolean doPublish, boolean useAsyncWithSyncInvoke)

次のものを構成します。

- 非同期レスポンス・エンドポイントのアドレス。

- 指定したアドレスでエンドポイントを公開するかどうか。詳細は、「非同期レスポンス・エンドポイントの公開」を参照してください。

- 同期操作用に非同期クライアント・トランスポートを有効にするかどうか。詳細は、「同期操作用の非同期クライアント・トランスポートの構成」を参照してください。

非同期レスポンス・エンドポイントのReplyToヘッダーとFaultToヘッダーの構成

非同期レスポンス・エンドポイントのjavax.xml.ws.wsaddressing.W3CEndpointReference型のすべての発信ReplyToおよびFaultToヘッダーに対して使用するアドレスは、AsyncClientTransportFeatureに引数として渡すことで構成できます。

たとえば、ReplyToヘッダー・アドレスのみを構成するには次のようにします。

W3CEndpointReference replyToAddress = "http://myserver.com:7001/myReliableService/myClientCallback";
AsyncClientTransportFeature asyncFeature = new AsyncClientTransportFeature(replyToAddress);
BackendService port = _service.getBackendServicePort(asyncFeature);

ReplyToとFaultToの両方のヘッダー・アドレスを構成するには次のようにします。

W3CEndpointReference replyToAddress = "http://myserver.com:7001/myReliableService/myClientCallback";
W3CEndpointReference faultToAddress = "http://myserver.com:7001/myReliableService/FaultTo";
AsyncClientTransportFeature asyncFeature = new AsyncClientTransportFeature(replyToAddress, faultToAddress);
BackendService port = _service.getBackendServicePort(asyncFeature);

次の表では、発信ReplyToおよびFaultToヘッダーのエンドポイント参照アドレスの構成に使用できるコンストラクタを示します。

表4-6 ReplyToおよびFaultToヘッダーを構成するためのコンストラクタ

コンストラクタ

説明

AsyncClientTransportFeature(javax.xml.ws.wsaddressing.W3CEndpointReference replyTo)

発信ReplyToヘッダーのエンドポイント参照アドレスを構成します。

AsyncClientTransportFeature(javax.xml.ws.wsaddressing.W3CEndpointReference replyTo, boolean doPublish)

次のものを構成します。

- 発信ReplyToヘッダーのエンドポイント参照アドレス。

- 指定したアドレスでエンドポイントを公開するかどうか。詳細は、「非同期レスポンス・エンドポイントの公開」を参照してください。

AsyncClientTransportFeature(javax.xml.ws.wsaddressing.W3CEndpointReference replyTo, boolean doPublish, boolean useAsyncWithSyncInvoke)

次のものを構成します。

- 発信ReplyToヘッダーのエンドポイント参照アドレス。

- 指定したアドレスでエンドポイントを公開するかどうか。詳細は、「非同期レスポンス・エンドポイントの公開」を参照してください。

- 同期操作用に非同期クライアント・トランスポートを有効にするかどうか。詳細は、「同期操作用の非同期クライアント・トランスポートの構成」を参照してください。

AsyncClientTransportFeature(javax.xml.ws.wsaddressing.W3CEndpointReference replyTo, javax.xml.ws.wsaddressing.W3CEndpointReference faultTo)

発信ReplyToおよびFaultToヘッダーのエンドポイント参照アドレスを構成します。

AsyncClientTransportFeature(javax.xml.ws.wsaddressing.W3CEndpointReference replyTo, javax.xml.ws.wsaddressing.W3CEndpointReference faultTo, boolean doPublish)

次のものを構成します。

- 発信ReplyToおよびFaultToヘッダーのエンドポイント参照アドレス。

- 指定したアドレスでエンドポイントを公開するかどうか。詳細は、「非同期レスポンス・エンドポイントの公開」を参照してください。

AsyncClientTransportFeature(javax.xml.ws.wsaddressing.W3CEndpointReference replyTo, javax.xml.ws.wsaddressing.W3CEndpointReference faultTo, boolean doPublish, boolean useAsyncWithSyncInvoke)

次のものを構成します。

- 発信ReplyToおよびFaultToヘッダーのエンドポイント参照アドレス。

- 指定したアドレスでエンドポイントを公開するかどうか。詳細は、「非同期レスポンス・エンドポイントの公開」を参照してください。

- 同期操作用に非同期クライアント・トランスポートを有効にするかどうか。詳細は、「同期操作用の非同期クライアント・トランスポートの構成」を参照してください。

非同期レスポンス・エンドポイントのコンテキスト・パスの構成

クライアントがサーブレットまたはWebアプリケーション・ベースのWebサービス内で実行している場合、ServletContextとコンテキスト・パスを使用して非同期レスポンス・エンドポイントを構成できます。次のように、AsyncClientTransportFeatureに引数として情報を渡します。

- サーブレット内で実行している場合:

AsyncClientTransportFeature asyncFeature =
new AsyncClientTransportFeature(getServletContext());

- WebサービスまたはEJBベースのWebサービス内で実行している場合:

import com.sun.xml.ws.api.server.Container;
...
Container c = ContainerResolver.getInstance().getContainer();
ServletContext servletContext = c.getSPI(ServletContext.class);
AsyncClientTransportFeature asyncFeature =
new AsyncClientTransportFeature(servletContext);

指定するコンテキストは、スコープを現在のアプリケーション内に指定されているか、または未使用コンテキストを参照している必要があります。別のデプロイ済みアプリケーションにスコープが設定されているコンテキストは参照できません。

注意:

AsyncClientTransportFeatureに対して空のコンストラクタを使用すると、Webサービスのランタイムは現在の機能がインスタンス化されたコンテナの検出を試み、使用可能なコンテナ・コンテキストを使用してエンドポイントを公開します。

次の表では、非同期レスポンス・エンドポイントのコンテキスト・パスの構成に使用できるコンストラクタを示します。

表4-7 非同期レスポンス・エンドポイントのコンテキスト・パスを構成するためのコンストラクタ

コンストラクタ

説明

AsyncClientTransportFeature(java.lang.Object context)

非同期レスポンス・エンドポイントのコンテキスト・パスを構成します。

AsyncClientTransportFeature(java.lang.Object context, boolean useAsyncWithSyncInvoke)

次のものを構成します。

- 非同期レスポンス・エンドポイントのコンテキスト・パス。

- 同期操作用に非同期クライアント・トランスポートを有効にするかどうか。詳細は、「同期操作用の非同期クライアント・トランスポートの構成」を参照してください。

非同期レスポンス・エンドポイントの公開

次のプロパティを構成するときにdoPublishブール値をAsycnClientTransportFeature()に引数として渡すことで、非同期レスポンス・エンドポイントを公開するかどうかを構成できます。

- 非同期レスポンス・エンドポイントのアドレス。表4-5を参照してください。

- ReplyToおよびFaultToヘッダー。表4-6を参照してください。

- 非同期レスポンス・エンドポイントのコンテキスト・パス。表4-7を参照してください。

doPublishをfalseに設定した場合は、非同期レスポンス・エンドポイントは自動的に発行されませんが、WS-Addressingヘッダーがアウトバウンドの非一方向メッセージに追加されます。このシナリオは次のプログラミング・モデルをサポートします。

- 非同期ポーリング(Responseオブジェクトへのアクセスは試みられません)

- ディスパッチ非同期ポーリング(Responseオブジェクトへのアクセスは試みられません)

- ディスパッチ一方向呼出し

- 同期トランスポート・オプションを使用する同期呼出し(デフォルト)

他のすべての非同期プログラミング・モデルについては、非同期レスポンス・エンドポイントが使用できる必要があり、doPublishがfalseに設定されている場合は、Webサービス・クライアントはアウトバウンド・リクエストを行う前にエンドポイントを公開する必要があります。

次の例では、非同期レスポンス・エンドポイント・アドレスを構成し、非同期レスポンス・エンドポイントを公開します。

String responseAddress = "http://localhost:7001/myReliableService/myReliableResponseEndpoint";
boolean doPublish = true;
AsyncClientTransportFeature asyncFeature =
new AsyncClientTransportFeature(responseAddress, doPublish);
BackendService port = _service.getBackendServicePort(asyncFeature);

同期操作用の非同期クライアント・トランスポートの構成

次のプロパティを構成するときに、useAsyncWithSyncInvokeブール・フラグを使用して、同期操作用の非同期クライアント・トランスポートを有効または無効にできます。

- 非同期レスポンス・エンドポイントのアドレス。表4-5を参照してください。

- ReplyToおよびFaultToヘッダー。表4-6を参照してください。

- 非同期レスポンス・エンドポイントのコンテキスト・パス。表4-7を参照してください。

次の例では、非同期レスポンス・エンドポイント・アドレスを構成し、同期操作に対して非同期クライアント・トランスポートを使用できるようにします。

String responseAddress = "http://localhost:7001/myReliableService/myReliableResponseEndpoint";
boolean useAsyncWithSyncInvoke = true;
AsyncClientTransportFeature asyncFeature =
new AsyncClientTransportFeature(responseAddress, useAsyncWithSyncInvoke);
BackendService port = _service.getBackendServicePort(asyncFeature);

非同期ハンドラ・インタフェースの開発

注意:

この項で説明するように単一の非同期ハンドラ・インスタンスをポートに設定した後、「JAX-WS参照実装の使用」で説明されているようにリクエスト単位の非同期ハンドラの構成を試みると、実行時例外が返されます。

「Webサービスを非同期に呼び出すためのクライアント・アーティファクトの構築」で説明されているように、非同期ハンドラ・インタフェースweblogic.jws.jaxws.client.async.AsyncClientHandlerFeatureは、リクエスト単位ベースではなく、ポートに単一の非同期ハンドラ・インスタンスを設定します。

たとえば、「Webサービスを非同期に呼び出すためのクライアント・アーティファクトの構築」で説明されているようにclientgenを使用してクライアント・クラスを構築するときは、次に示すように、非同期ハンドラ・インタフェースが生成されます。

例4-1 非同期ハンドラ・インタフェースの例

import javax.xml.ws.Response;

/**
* This class was generated by the JAX-WS RI.
* Oracle JAX-WS 2.1.5
* Generated source version: 2.1
*
*/
public interface BackendServiceAsyncHandler {

/**
*
* @param response
*/
public void onDoSomethingResponse(Response<DoSomethingResponse> response);

}

非同期ハンドラ・インタフェースは、ポート・インタフェースと同じパッケージの一部として生成され、サービスで定義されている操作に対するレスポンスを受け取るために必要なメソッドを表します。クライアントのコードでこのインタフェースをインポートして実装し、厳格に型指定された方法で非同期レスポンスを受信して処理する手段を提供できます。

ポートに単一の非同期ハンドラ・インスタンスを設定するには、Webサービス・プロキシまたはディスパッチを作成するときに、パラメータとしてweblogic.jws.jaxws.client.async.AsyncClientHandlerFeatureのインスタンスを渡します。レスポンス・メッセージを受信したときに呼び出される非同期ハンドラの名前を指定します。

次の例では、非同期ハンドラ・インタフェースの開発方法を示します。この例を見ると、AsyncClientHandlerFeatureを初期化し、バックエンド・サービスで呼出しを行うために使用されるポートに非同期ハンドラの実装を接続する方法がわかります。この例は、例3-2「非同期Webサービス・クライアントのベスト・プラクティスの例」からの抜粋です。

例4-2 非同期ハンドラ・インタフェースの開発の例

import weblogic.jws.jaxws.client.async.AsyncClientHandlerFeature;
...
BackendServiceAsyncHandler handler = new BackendServiceAsyncHandler() {
public void onDoSomethingResponse(Response<DoSomethingResponse> res) {
// ... Handle Response ...
try {
DoSomethingResponse response = res.get();
_lastResponse = response.getReturn();
System.out.println("Got async response: " + _lastResponse);
} catch (Exception e) {
_lastResponse = e.toString();
e.printStackTrace();
}
}
};
AsyncClientHandlerFeature handlerFeature = new AsyncClientHandlerFeature(handler);
features.add(handlerFeature);
_features = features.toArray(new WebServiceFeature[features.size()]);
BackendService anotherPort = _service.getBackendServicePort(_features);
...
// Make the invocation. Our asynchronous handler implementation (set
// into the AsyncClientHandlerFeature above) receives the response.
String request = "Dance and sing";
System.out.println("Invoking DoSomething asynchronously with request: " + request);
anotherPort.doSomethingAsync(request);

レスポンスへのユーザー定義リクエスト・コンテキストの伝播

weblogic.wsee.jaxws.JAXWSProperties APIで定義されている次のプロパティを使用すると、非同期ハンドラ・インスタンスの状態に依存することなく、ユーザー定義のリクエスト・コンテキスト情報をレスポンス・メッセージに伝播できます。

非同期ハンドラ・インスタンスはいつでも作成される可能性があります(たとえば、クライアントのサーバーがダウンして再起動されるとき)。したがって、非同期ハンドラ・インタフェースにリクエスト・コンテキストを格納しても役に立ちません。

次の表では、JAXWSPropertiesのプロパティを定義します。

表4-8 JAXWSProperties APIによってサポートされるプロパティ

プロパティ

説明

MESSAGE_ID

リクエストのメッセージID。クライアントでは、リクエスト・コンテキストにこのプロパティを設定し、リクエストごとのメッセージIDヘッダーの自動生成をオーバーライドできます。

PERSISTENT_CONTEXT

クライアントまたは通信チャネルで必要なコンテキスト・プロパティ。Webサービス・クライアントでは、コンテキスト・プロパティがシリアライズ可能である場合、リクエスト・メッセージに対してコンテキスト・プロパティを保持できます。これらのプロパティは、非同期ハンドラが呼び出されるときに、Responseオブジェクトから使用可能なレスポンス・コンテキスト・マップで使用できます。詳細は、「レスポンスへのリクエスト・コンテキストの伝播」を参照してください。

RELATES_TO

レスポンスが関連付けられているメッセージID。

REQUEST_TIMEOUT

非同期クライアント・トランスポートを使用する同期操作の場合、ブロックしてレスポンスを待機する最大時間。このプロパティのデフォルトは0で、タイムアウトしないことを示します。

さらに、Webサービス・クライアントでは、コンテキスト・プロパティがシリアライズ可能である場合、リクエスト・メッセージに対してコンテキスト・プロパティを保持できます。コンテキスト・プロパティは、クライアントまたは通信チャネルで必要な情報を格納できます。メッセージのプロパティは、weblogic.wsee.jaxws.JAXWSProperties.PERSISTENT_CONTEXTマップ・プロパティの一部として格納し、レスポンス・メッセージが返された後で取得できます。詳細は、「レスポンスへのリクエスト・コンテキストの伝播」を参照してください。

ファイアウォールの内側からの非同期Webサービス・クライアントの使用(接続作成)

Webサービスの接続作成は、非同期クライアント・トランスポートの代わりとなるクライアント・ポーリング・メカニズムであり、通常はファイアウォールの内側にあるクライアントのサポートを提供します。http://docs.oasis-open.org/ws-rx/wsmc/200702の接続作成仕様で説明されているように、WebLogic ServerはWS-MakeConnectionバージョン1.1をサポートし、バージョン1.0と下位互換性があります。

接続作成の具体的な機能は次のとおりです。

- リクエスト・メッセージの送信に使用された開始トランスポート・リクエストから、レスポンス・メッセージを切り離すことができるようにします(非同期クライアント・トランスポートと似ています)。

- アドレス可能ではなく着信接続を受け付けることができないWebサービス・クライアントをサポートします(たとえば、ファイアウォールの内側のクライアント)。

- WS-MakeConnectionの仕様で定義されているように、Webサービス・クライアントがMC-Initiatorとして機能し、WebサービスがMC-Receiverとして機能できるようにします。

Webサービスの接続作成の仕様から抜粋した次の図では、標準的な接続作成のメッセージ・フローが示されています。

図4-2 接続作成のメッセージ・フロー

「図4-2 接続作成のメッセージ・フロー」の説明

前の図で示されているように、接続作成のメッセージ・フローは次のようになります。

1. getQuote()リクエスト・メッセージが、Webサービス・クライアント(MCイニシエータ)からWebサービス(MCレシーバ)に送信されます。ReplyToヘッダーには、MCイニシエータのUUIDを指定する接続作成の匿名URIが含まれます。
MCレシーバがgetQuote()メッセージを受信します。ReplyToヘッダーに接続作成匿名URIが含まれる場合はレスポンス・メッセージを接続の戻りチャネルで返送できることを示し、ない場合はクライアントが接続作成ポーリングを使用してレスポンス・メッセージを取得します。

2. MCレシーバは、空のレスポンス(HTTP 202)をMCイニシエータに返送することで接続を閉じます。
空のレスポンスを受信すると、MCイニシエータはポーリング・メカニズムを初期化して開始し、以降のポーリングをMCレシーバに送信できるようにします。具体的には、MCイニシエータのポーリング・メカニズムは、連続するポーリング間の時間に対して構成されている間隔に有効期限が設定されたタイマーを開始します。

3. タイマーが切れると、MCイニシエータは、同じ接続作成匿名URI情報を格納した接続作成メッセージをMCレシーバに送信します。

4. MCレシーバはgetQuote()操作の処理を完了していないので、MCイニシエータに返送できるレスポンスはありません。その結果、MCレシーバは、再び空のレスポンス(HTTP 202)を返送することで現時点では送信できるレスポンスがないことを示し、接続を閉じます。
空のメッセージを受信すると、MCイニシエータは接続作成ポーリング・メカニズムのタイマーを再起動します。

タイマーが切れる前に、getQuote()操作が完了します。元のリクエストのReplyToヘッダーには接続作成匿名URIが含まれていたので、MCレシーバはレスポンスを格納し、アドレスが一致する次の接続作成メッセージの受信を待ちます。

5. タイマーが切れると、MCイニシエータは、同じ接続作成匿名URI情報を格納した接続作成メッセージをMCレシーバに送信します。

6. 接続作成メッセージを受信すると、MCレシーバは格納されているレスポンス・メッセージを取得し、受信した接続作成メッセージに対するレスポンスとして送信します。
MCイニシエータはレスポンス・メッセージを受信し、接続作成ポーリング・メカニズムを終了します。

ファイアウォールの内側から非同期呼出しを使用するときは、接続作成トランスポートを使用することをお薦めします。サポートされるプログラミング・モデルの一覧については、表4-2「Webサービスの非同期呼出しのトランスポート・タイプ」を参照してください。

次の項では、Webサービスとクライアントで接続作成を有効にして構成する方法を説明します。

- Webサービスでの接続作成の有効化と構成

- Webサービス・クライアントでの接続作成の有効化と構成

Webサービスでの接続作成の有効化と構成

接続作成を有効にするには、接続作成ポリシー・アサーションをWebサービスにアタッチした後、標準のJAX-WSクライアントAPIを使用してクライアントからそのメソッドを呼び出します。ポリシーをWebサービスにアタッチするには、次のいずれかの方法を使用します。

- @PolicyアノテーションをJWSファイルに追加します。接続作成ポリシーをアタッチできるのはクラス・レベルだけです。

- ポリシーに対する参照をWebサービスのWSDLに追加します。

次の項では、Webサービスで接続作成を有効にするために必要な手順を説明します。

- Webサービスの接続作成WS-Policyファイルの作成(オプション)

- 接続作成を有効にするためのJWSファイルのプログラミング

Webサービスの接続作成WS-Policyファイルの作成(オプション)

WS-Policyファイルは、WS-Policy仕様に準拠するポリシー・アサーションを含むXMLファイルです。この場合、WS-PolicyファイルにはWebサービスの接続作成のポリシー・アサーションが含まれています。

WebLogic Serverには、標準的な接続作成アサーションを含むWS-Policyファイルがあらかじめパッケージ化されているので、独自のWS-Policyファイルを作成しない場合は、このファイルを使用できます。次の表に、接続作成をサポートするあらかじめパッケージ化されているWS-Policyファイルを示します。場合によっては、ポリシーによって信頼性のあるメッセージングと接続作成の両方が有効化されます。詳細は、付録A「Webサービスの信頼性のあるメッセージングと接続作成のためのあらかじめパッケージ化されたWS-Policyファイル」を参照してください。

注意:

接続作成ポリシーをアタッチできるのはクラス・レベルのみです。メソッド・レベルで接続作成ポリシーをアタッチすることはできません。

表4-9 あらかじめパッケージ化されていて接続作成をサポートするWS-Policyファイル

あらかじめパッケージ化されているWS-Policyファイル

説明

Mc1.1.xml

Webサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。WS-Policy 1.5プロトコルが使用されます。「Mc1.1.xml(WS-Policyファイル)」を参照してください。

Mc.xml

Webサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。WS-Policy 1.2プロトコルが使用されます。「Mc.xml(WS-Policyファイル)」を参照してください。

Reliability1.2_ExactlyOnce_WithMC1.1.xml

サービス品質に関するポリシー・アサーションを指定します。Webサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。「Reliability1.2_ExactlyOnce_WithMC1.1.xml(WS-Policyファイル)」を参照してください。

Reliability1.2_SequenceSTR.xml

信頼性のあるシーケンスでメッセージを保護するために、CreateSequenceメッセージで参照されるwsse:SecurityTokenReferenceをランタイムが使用するように指定します。Webサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。「Reliability1.2_SequenceSTR.xml(WS-Policyファイル)」を参照してください。

Reliability1.0_1.2.xml

1.2と1.0のWS-Reliableメッセージング・ポリシー・アサーションを結合します。1.2バージョンのポリシー・アサーションはWebサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。このサンプルは、適切なポリシーの選択に基づいて実行時に適用されるポリシー・アサーションを決定します。「Reliability1.0_1.2.xml(WS-Policyファイル)」を参照してください。

WebLogic Serverに含まれる、あらかじめパッケージ化されている接続作成WS-Policyファイルの1つを使用できます。これらのファイルは、ほとんどのユースケースに適合しています。あらかじめパッケージ化されているファイルは変更できません。値がニーズを満たさない場合は、カスタムのWS-Policyファイルを作成する必要があります。たとえば、Webサービスのクライアント側でリクエストされるように接続作成のサポートを構成する場合があります。接続作成ポリシー・アサーションは、WS-PolicyAssertions仕様(https://www.ibm.com/developerworks/library/specification/ws-polas)に準拠します。

接続作成アサーションを含むカスタムWS-Policyファイルを作成するには、次のガイドラインを使用してください。

- WS-Policyファイルのルート要素は常に<wsp:Policy>です。

- Webサービスの接続作成を構成するには、<wsmc:MCSupported>子要素を追加して、Webサービスの接続作成のサポートを定義します。

- <wsmc:MCSupported>子要素は、1つのポリシー属性Optionalを含み、接続作成をWebサービス・クライアントで構成する必要があるかどうかを指定します。この属性はtrueまたはfalseに設定でき、デフォルトではtrueに設定されます。falseに設定した場合は、接続作成の使用は必須であり、ReplyToヘッダーとFaultToヘッダー(指定する場合)の両方に接続作成匿名URIが含まれる必要があります。

次の例では、Webサービスで接続作成を有効にし、Webサービス・クライアントで接続作成を有効にする必要があることを指定しています。この例では、WS-Policy 1.5プロトコルを使用しています。

<?xml version="1.0"?>
<wsp15:Policy  xmlns:wsp15="http://www.w3.org/ns/ws-policy"
xmlns:wsmc="http://docs.oasis-open.org/ws-rx/wsmc/200702">
<wsmc:MCSupported wsp15:Optional="false" />
</wsp15:Policy>

接続作成を有効にするためのJWSファイルのプログラミング

この項では、あらかじめパッケージ化されている接続作成WS-Policyファイルまたはカスタム接続作成WS-Policyファイルを使用して、Webサービスで接続作成を有効にする方法を説明します。カスタム・ポリシー・ファイルの作成の詳細は、「Webサービスの接続作成WS-Policyファイルの作成(オプション)」を参照してください。

接続作成アサーションが含まれるWS-PolicyファイルをWebサービスに追加するよう指定するには、JWSファイルで@Policyアノテーションを使用します。WebLogic Serverでは、あらかじめパッケージ化されているWS-Policyファイルのセットが提供されます。付録A「Webサービスの信頼性のあるメッセージングと接続作成のためのあらかじめパッケージ化されたWS-Policyファイル」を参照してください。

Webサービスの信頼性のあるメッセージングで@Policyアノテーションを使用する場合は、次のガイドラインを参照してください。

- 接続作成ポリシーをアタッチできるのはクラス・レベルのみです。メソッド・レベルで接続作成ポリシーをアタッチすることはできません。

- uri属性を使用して、ポリシー・ファイルのビルド時の場所を以下のように指定します。

- 独自のWS-Policyファイルを作成した場合は、JWSファイルを基準として相対的に場所を指定します。例:

@Policy(uri="McPolicy.xml", attachToWsdl=true)

この例では、McPolicy.xmlファイルはJWSファイルと同じディレクトリに置かれています。

- あらかじめパッケージ化されているWS-Policyファイルの1つか、共有Java EEライブラリにパッケージ化されているWS-Policyファイルを指定するには、そのポリシー・ファイルの名前とパスとともにpolicy:接頭辞を使用します。この構文ではビルド時のjwsc Antタスクに、ファイル・システムの実際のファイルを探させず、Webサービスが、サービスのデプロイ時にWebLogic ServerからWS-Policyファイルを取得することを通知しています。

注意:

共有Java EEライブラリは、様々なエンタープライズ・アプリケーション内にパッケージ化されている複数のWebサービスとWS-Policyファイルを共有する場合に有用です。WS-Policyファイルが共有Java EEライブラリのMETA-INF/policiesまたはWEB-INF/policiesディレクトリに置かれているかぎり、ポリシー・ファイルはWebサービスの同じアーカイブにパッケージ化されている場合と同様に指定できます。ライブラリの作成、およびWebサービスがポリシー・ファイルを見つけることができるようにするための環境設定については、『Oracle WebLogic Serverアプリケーションの開発』の共有Java EEライブラリおよびオプション・パッケージの作成に関する項を参照してください。

- ポリシー・ファイルをWeb上で公開するよう指定するには、次の例に示すとおり、URLと共にhttp:接頭辞を使用します。

@Policy(uri="http://someSite.com/policies/mypolicy.xml"
attachToWsdl=true)

- @PolicyアノテーションのattachToWsdl属性を設定して、ポリシー・ファイルをWebサービスのパブリック規約が記述されたWSDLファイルに付加するかどうかを指定できます。通常は、クライアント・アプリケーションでWebサービスの信頼性のあるメッセージング機能が認識されるよう、パブリックなものとしてポリシーを公開します。そのため、この属性のデフォルト値はtrueです。

@Policyアノテーションの詳細は、『Oracle WebLogic Server WebLogic Webサービス・リファレンス』のweblogic.jws.Policyに関する項を参照してください。

次の例では、接続作成を有効にする簡単なJWSファイルを示します。太字で示されたJavaコードに対応するコーディングのガイドラインについては、例の後の説明を参照してください。

package examples.webservices.async

import javax.jws.WebMethod;
import javax.jws.WebService;
import weblogic.jws.Policy;

/**
* Simple reliable Web Service.
*/

@WebService(name="HelloWorldPortType",
serviceName="HelloWorldService")

@Policy(uri="McPolicy.xml", attachToWsdl=true)
public class HelloWorldImpl {
private static String onewaySavedInput = null;

/**
* A one-way helloWorld method that saves the given string for later
* concatenation to the end of the message passed into helloWorldReturn.
*/
@WebMethod()
public void helloWorld(String input) {
System.out.println(" Hello World " + input);
onewaySavedInput = input;
}

/**
* This echo method concatenates the saved message from helloWorld
* onto the end of the provided message, and returns it.
*/
@WebMethod()
public String echo(String input2) {
System.out.println(" Hello World " + input2 + onewaySavedInput);
return input + onewaySavedInput;
}
}

前のサンプルでは、カスタムMcPolicy.xmlポリシー・ファイルがクラス・レベルでWebサービスにアタッチされています。つまり、ポリシー・ファイルはWebサービスのすべてのパブリック操作に適用されます。接続作成ポリシーをアタッチできるのはクラス・レベルのみです。メソッド・レベルで接続作成ポリシーをアタッチすることはできません。

ポリシー・ファイルはWSDLファイルにアタッチされます。使用可能なあらかじめパッケージ化されているポリシーと、カスタム・ポリシーの作成の詳細は、「Webサービスの接続作成WS-Policyファイルの作成(オプション)」を参照してください。

echo()メソッドは、@WebMethodJWSアノテーションでマークされています。これは、このメソッドがechoというパブリック操作であるということです。@Policyアノテーションがあるために、この操作では接続作成トランスポート・プロトコルが使用されます。

Webサービス・クライアントでの接続作成の有効化と構成

注意:

接続作成と非同期クライアント・トランスポート機能を一緒に使用することはできません。同じWebサービス・クライアントで両方の機能を有効にしようとすると、エラーが返されます。非同期クライアント・トランスポートの詳細は、「スケーラブルな非同期JAX-WSクライアントの開発(非同期クライアント・トランスポート)」を参照してください。

非同期コールバック・ハンドラ・プログラミング・モデルを使用するときは、非同期ハンドラ機能AsyncClientHandlerFeatureを使用することをお薦めします。詳細は、「非同期ハンドラ・インタフェースの開発」を参照してください。

Webサービス・クライアントで接続作成を有効にするには、Webサービス・プロキシまたはディスパッチを作成するときにパラメータとしてweblogic.wsee.mc.api.McFeatureのインスタンスを渡します。接続作成を有効にする方法の簡単な例を次に示します。

注意:

この例では、同期メソッドに同期トランスポートを使用します。同期メソッドのトランスポートとして接続作成を構成する方法は、「同期メソッドのトランスポートとしての接続作成の構成」を参照してください。

package examples.webservices.myservice.client;

import weblogic.wsee.mc.api.McFeature;
...
List<WebServiceFeature> features = new ArrayList<WebServiceFeature>();
...
McFeature mcFeature = new McFeature();
features.add(mcFeature);
...
// ... Implement asynchronous handler interface as described in
//  Developing the Asynchronous Handler Interface.
// ....
AsyncClientHandlerFeature handlerFeature = new AsyncClientHandlerFeature(handler);
features.add(handlerFeature);
_features = features.toArray(new WebServiceFeature[features.size()]);
BackendService port = _service.getBackendServicePort(_features);
...
// Make the invocation. Our asynchronous handler implementation (set
// into the AsyncClientHandlerFeature above) receives the response.
String request = "Dance and sing";
System.out.println("Invoking DoSomething asynchronously with request: " + request);
anotherPort.doSomethingAsync(request);
..
}
}

次の項では、Webサービス・クライアントで接続作成の特定の機能を構成する方法を説明します。

- 接続作成メッセージ送信の有効時間の構成

- ポーリング間隔の構成

- 指数関数的バックオフの構成

- 同期メソッドのトランスポートとしての接続作成の構成

接続作成メッセージ送信の有効時間の構成

表4-10では、MCイニシエータがMCレシーバへの接続作成メッセージの送信を停止するまでの最大時間を構成するためのMcFeatureメソッドについて説明します。

表 4-10 接続作成メッセージ送信の有効時間を構成するためのメソッド

メソッド

説明

String getsExpires()

現在構成されている有効期限の値を返します。

void setExpires(String expires)

有効期限を設定します。

指定する値はXMLスキーマの期間を表す字句形式(PnYnMnDTnHnMnS)に従った正の値でなければなりません。ここで、nYは年数、nMは月数、nDは日数を表し、Tは日付/時刻のセパレータ、nHは時間数、nMは分数、nSは秒数を表します。この値のデフォルトはP1D (1日)。

ポーリング間隔の構成

表4-11では、空のレスポンス・メッセージを受信した後でMCイニシエータがMCレシーバに接続作成メッセージを送信するまでに経過する必要のある時間を構成するためのMcFeatureメソッドについて説明します。指定されている時間内にMCイニシエータが特定のメッセージに対する空ではないレスポンスを受信しない場合、MCイニシエータは別の接続作成メッセージを送信します。

表4-11 ポーリング間隔を構成するためのメソッド

メソッド

説明

String getInterval()

ポーリング間隔を取得します。

void setInterval(String pollingInterval)

ポーリング間隔を設定します。

指定する値はXMLスキーマの期間を表す字句形式(PnYnMnDTnHnMnS)に従った正の値でなければなりません。ここで、nYは年数、nMは月数、nDは日数を表し、Tは日付/時刻のセパレータ、nHは時間数、nMは分数、nSは秒数を表します。この値のデフォルトはP0DT5S (5秒)。

次の例では、ポーリング間隔を36時間に設定しています。

...
McFeature mcFeature = new McFeature();
mcFeature.setInterval("P0DT36H")
MyService port = service.getMyServicePort(mcFeature);
...

指数関数的バックオフの構成

表4-12では、指数関数的バックオフ・フラグを構成するためのMcFeatureメソッドについて説明します。このフラグは、「ポーリング間隔の構成」で説明されているポーリング間隔を、指数関数的バックオフ・アルゴリズムを使用して調整するかどうかを指定します。ポーリング間隔で指定されている時間が経過してもMCイニシエータが空ではないレスポンスを受信しない場合、指数関数的バックオフ・アルゴリズムを使用して、MCイニシエータがレスポンスを受信しないときの連続する再送信のタイミングが設定されます。

指数関数的バックオフ・アルゴリズムは、ポーリングの間隔が、ポーリング間隔を基に指数的に増えるように指定します。たとえば、ポーリング間隔が2秒で、指数関数的バックオフ要素が設定されている場合、レスポンスを受信しない場合の連続ポーリングの間隔は、2、4、8、16、32というように増えていきます。

デフォルト値はfalseであり、連続するポーリングの間隔は指数的に増えず、同じ値が維持されます。

表4-12 指数関数的バックオフを構成するためのメソッド

メソッド

説明

boolean isExponentialBackoff()

指数関数的バックオフが有効かどうかを示すブール値を返します。

void setExponentialBackoff(boolean backoff)

指数関数的バックオフ・フラグを設定します。有効な値はtrueとfalseです。デフォルトはfalseです。

次の例では、指数関数的バックオフ・フラグを有効にしています。

...
McFeature mcFeature = new McFeature();
mcFeature.setMessageInterval(P0DT36H)
mcFeature.setExponentialBackoff(true);
MyService port = service.getMyServicePort(mcFeature);
...

同期メソッドのトランスポートとしての接続作成の構成

デフォルトでは、クライアントで接続作成が有効であっても、同期メソッドは同期トランスポートを使用します。同期メソッドのトランスポートとして接続作成を使用するように、クライアントを構成できます。この場合、空ではないレスポンス・メッセージを受信するまで、構成されているポーリング間隔(「ポーリング間隔の構成」を参照)に基づいて、MCイニシエータは接続作成メッセージを送信します。

同期メソッドに使用するトランスポート・プロトコルとして接続作成を構成するには、次のいずれかのメソッドを使用します。

- 新しいMcFeature()オブジェクトをインスタンス化するとき、同期メソッドのトランスポート・プロトコルとして接続作成を使用するかどうかを指定するブール値を、パラメータとして渡すことができます。例:

...
McFeature mcFeature = new McFeature(true);
MyService port = service.getMyServicePort(mcFeature);
...

- 表4-13で示されているMcFeatureメソッドを使用します。例:

...
McFeature mcFeature = new McFeature();
mcFeature.setUseMCWithSyncInvoke(true);
MyService port = service.getMyServicePort(mcFeature);
...

表4-13 同期メソッドのサポートを構成するためのメソッド

メソッド

説明

boolean isUseMCWithSyncInvoke()

同期メソッドのサポートが有効かどうかを示すブール値を返します。

void setUseMCWithSyncInvoke(boolean useMCWithSyncInvoke)

同期メソッド・サポート・フラグを設定します。有効な値はtrueとfalseです。デフォルトはfalseです。

weblogic.wsee.jaxws.JAXWSProperties.REQUEST_TIMEOUTプロパティを使用すると、同期メソッドがブロックしてレスポンスを待機する最大時間を設定できます。このプロパティのデフォルトは0で、タイムアウトしないことを示します。メッセージ・プロパティの設定の詳細は、「レスポンスへのユーザー定義リクエスト・コンテキストの伝播」を参照してください。

JAX-WS参照実装の使用

JAX-WS参照実装(RI)は、次のプログラミング・モデルをサポートします。

- java.util.concurrent.Futureインタフェースを使用する非同期クライアント・ポーリング。

- リクエスト単位の非同期コールバック・ハンドラ。呼出し元のクライアントが、呼出し時にコールバック・ハンドラを指定します。レスポンスが使用できるときは、レスポンスを処理するためにコールバック・ハンドラが呼び出されます。

非同期クライアント・トランスポート機能とは異なり、JAX-WS RIはWS-Addressingに対する非常に制限されたサポートを提供します。次のものが含まれます。

- クライアント側アウトバウンドWS-Addressingヘッダーの追加の手動サポート。

- レスポンスを受信するためのクライアント側エンドポイントの公開の手動サポート。

- 正しくないクライアント側プログラミング・モデルの検出はサポートしません(たとえば、同期呼出しはハングします)。

- クライアント側またはサービス側の再起動時の情報の保持はサポートしません。

次に示すサンプル・クライアント・ファイルAsyncClientには、AddNumbersServiceサービスのAddNumbersAsyncメソッドを非同期的に呼び出すAddNumbersTestDriveというメソッドが定義されています。太字で示したJavaコードについては後ほど説明します。

package examples.webservices.async.client;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import javax.xml.ws.BindingProvider;

import java.util.concurrent.Future;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Response;

public class AsyncClient  {

private AddNumbersPortType port = null;
protected void setUp() throws Exception {
AddNumbersService service = new AddNumbersService();
port = service.getAddNumbersPort();
String serverURI = System.getProperty("wls-server");
((BindingProvider) port).getRequestContext().put(
BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"http://" + serverURI + "/JAXWS_ASYNC/AddNumbersService");
}

/**
*
* Asynchronous callback handler
*/
class AddNumbersCallbackHandler implements AsyncHandler<AddNumbersResponse> {
private AddNumbersResponse output;
public void handleResponse(Response<AddNumbersResponse> response) {
try {
output = response.get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
AddNumbersResponse getResponse() {
return output;
}
}

public void AddNumbersTestDrive() throws Exception {
int number1 = 10;
int number2 = 20;

// Asynchronous Callback method
AddNumbersCallbackHandler callbackHandler =
new AddNumbersCallbackHandler();
Future<?> resp = port.addNumbersAsync(number1, number2,
callbackHandler);
// For the purposes of a test, block until the async call completes
resp.get(5L, TimeUnit.MINUTES);
int result = callbackHandler.getResponse().getReturn();

// Polling method
Response<AddNumbersResponse> addNumbersResp =
port.AddNumbersAsync(number1, number2);
while (!addNumbersResp.isDone()) {
Thread.sleep(100);
}
AddNumbersResponse reply = addNumbersResp.get();
System.out.println("Server responded through polling with: " +
reply.getResponseType());
}
}

次の例では、非同期ポーリングと非同期コールバック・ハンドラの両方のプログラミング・モデルを実装する手順を示します。

非同期コールバック・ハンドラを実装するには:

1. javax.xml.ws.AsyncHandler<T>インタフェースを実装する非同期ハンドラを作成します。(http://download.oracle.com/javaee/5/api/javax/xml/ws/AsyncHandler.htmlを参照)。この非同期ハンドラには、handleResponseメソッドを定義します。このメソッドにより、非同期的に呼び出されるサービス・エンドポイント操作の完了時に、クライアントがコールバック通知を受信することが可能になります。タイプはAddNumberResponseに設定する必要があります。

class AddNumbersCallbackHandler implements AsyncHandler<AddNumbersResponse> {
private AddNumbersResponse output;

public void handleResponse(Response<AddNumbersResponse> response) {
try {
output = response.get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();

}
}

AddNumbersResponse getResponse() {
return output;
}
}

2. 非同期コールバック・ハンドラをインスタンス化します。

AddNumbersCallbackHandler callbackHandler =
new AddNumbersCallbackHandler();

3. AddNumbersService Webサービスをインスタンス化し、非同期バージョンのWebサービス・メソッドaddNumbersAsyncを呼び出して非同期コールバック・ハンドラにハンドルを渡します。

AddNumbersService service = new AddNumbersService();
port = service.getAddNumbersPort();
...

Future<?> resp = port.addNumbersAsync(number1, number2,
callbackHandler);

java.util.concurrent.Future(http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Future.htmlを参照)は、非同期計算の結果を表現し、非同期タスクのステータスの確認、結果の取得、タスクの実行の取消を可能にします。

4. 非同期計算の結果を取得します。このサンプルでは、計算の完了を待機するためのタイムアウト値を指定しています。

resp.get(5L, TimeUnit.MINUTES);

5. コールバック・ハンドラを使用してレスポンス・メッセージにアクセスします。

int result = callbackHandler.getResponse().getReturn();

非同期ポーリング・メカニズムを実装するには:

1. AddNumbersService Webサービスをインスタンス化し、非同期バージョンのWebサービス・メソッドaddNumbersAsyncを呼び出します。

Response<AddNumbersResponse> addNumbersResp =
port.AddNumbersAsync(number1, number2);

2. メッセージを受信するまでスリープします。

while (!addNumbersResp.isDone()) {
Thread.sleep(100);

3. レスポンスをポーリングします。

AddNumbersResponse reply = addNumbersResp.get();

レスポンスへのリクエスト・コンテキストの伝播

WebLogic Serverには、リクエストおよびレスポンス・メッセージの内容に関係なく、ビジネス・コンテキスト(ビジネス・レベルのメッセージIDなど)をリクエスト・メッセージにアタッチして、レスポンスが返されたときにアクセスできるようにする強力な機能があります。たとえば、他の方法ではレスポンス・メッセージで利用できないビジネス・レベルのメッセージIDを使用できます。メッセージにこの情報を伝播することにより、レスポンス・メッセージが返されたときに情報にアクセスできます。

Webサービス・クライアントは、シリアライズ可能でさえあれば任意のリクエスト・メッセージ・コンテキスト・プロパティを格納できます。メッセージ・コンテキスト・プロパティは、weblogic.wsee.jaxws.JAXWSProperties.PERSISTENT_CONTEXTマップ・プロパティの一部として格納でき、レスポンス・メッセージが返された後で取得できます。

次の例では、PERSISTENT_CONTEXTマップ・プロパティを使用してメッセージ・コンテキスト・プロパティを定義および設定する方法を示します。

例4-3 メッセージ・コンテキスト・プロパティの設定

import weblogic.wsee.jaxws.JAXWSProperties;
. . .
MyClientPort port = myService.getPort();
Map<String, Serializable> clientPersistProps =
port.getRequestContext().get(JAXWSProperties.PERSISTENT_CONTEXT);
Serializable obj = <my_property>;
clientPersistProps.put("MyProperty", obj);

port.myOperationAsync(<args>, new AsyncHandler<MyOperationResponse>() {
public void handleResponse(Response<MyOperationResponse> res) {
try {
// Get the actual response
MyOperationResponse response = res.get().getReturn();

// Get the property stored when making request. Note, this property did not get
// passed over the wire with the reuqest. The Web services runtime stores it.
Map<String, Serializable> clientPersistProps =
res.getContext().get(JAXWSProperties.PERSISTENT_CONTEXT);
Serializable obj = clientPersistProps.get("MyProperty");
// Do something with MyProperty
} catch (Exception e) {
// Error handling
}
}
});
...

Webサービスの非同期呼出しのモニタリング

管理コンソールを使用すると、呼出し、エラー、フォルトの数など、Webサービスを非同期に呼び出すクライアントの実行時情報をモニターできます。Webサービス・クライアントをモニターするには、左ペインの「デプロイメント」ノードをクリックし、右ペインに表示される「デプロイメント」表で、Webサービス・クライアントがパッケージ化されているエンタープライズ・アプリケーションを探します。「+」ノードをクリックしてアプリケーションを展開し、Webサービス・クライアントが存在するアプリケーション・モジュールをクリックします。「監視」タブをクリックし、「Webサービス・クライアント」タブをクリックします。

接続作成トランスポート・プロトコルを使用している場合、Webサービスまたはクライアントの接続作成匿名エンドポイントを監視できます。匿名エンドポイントごとに、受信メッセージ数、保留中メッセージ数などの実行時監視情報が表示されます。

「この表のカスタマイズ」をクリックすることで、表に表示される情報をカスタマイズできます。

Webサービスの接続作成匿名エンドポイントを監視するには、左ペインの「デプロイメント」ノードをクリックし、右ペインに表示される「デプロイメント」表でWebサービスがパッケージ化されているエンタープライズ・アプリケーションを探します。「+」ノードをクリックしてアプリケーションを展開すると、「Webサービス」カテゴリにアプリケーション内のWebサービスのリストが表示されます。Webサービス名をクリックし、「監視」→「ポート」→「接続作成」を選択します。

Webサービス・クライアントの接続作成匿名エンドポイントを監視するには、左ペインの「デプロイメント」ノードをクリックし、右ペインに表示される「デプロイメント」表でWebサービス・クライアントがパッケージ化されているエンタープライズ・アプリケーションを探します。「+」ノードをクリックしてアプリケーションを展開し、Webサービス・クライアントが存在するアプリケーション・モジュールをクリックします。「監視」タブをクリックし、「Webサービス・クライアント」タブをクリックします。次に、「監視」→「サーバー」→「接続作成」をクリックします。

非同期Webサービス・メッセージングのクラスタリングの考慮事項

Webサービス・クライアントがクラスタで実行するときは、非同期呼出しの非同期レスポンス・エンドポイントにレスポンス・メッセージを正しく配信できるように、特別に考慮する必要があります。「非同期クライアント・トランスポート機能の有効化と構成」で説明したように、非同期レスポンス・エンドポイントはAsyncClientTransportFeatureで定義します。

次の図で示すようなシナリオについて考えます。

図4-3 エラーになるクラスタリング・シナリオ

「図4-3 エラーになるクラスタリング・シナリオ」の説明

前の図で示されているシナリオ:

- 2つのノードから成るクラスタがクライアント・アプリケーションをホストします。ノード名はServer1とServer2です。クラスタには簡単なロード・バランシング・フロントエンド・プロキシが含まれます。

- クライアント・アプリケーションはClientWebAppという名前のWebアプリケーションで、クラスタに同じようにデプロイされています。つまり、Webアプリケーションはクラスタ内の両方のメンバー・サーバーで実行します。

- ClientWebAppアプリケーションの外部クライアントが、クラスタのフロントエンド・アドレスを通してリクエストを行います。

次のようなシーケンスについて考えます。

1. 外部クライアントは、クラスタのフロントエンドを介してClientWebAppにページを要求します。

2. クラスタのフロントエンドはページ・リクエストのロード・バランシングを行い、Server1のClientWebAppにページ・リクエストを送ります。

3. Server1のClientWebAppはWebサービス・クライアントBackendServiceClientのインスタンスを作成し、バックエンド・サービスBackendServiceと通信します。BackendServiceClientを作成すると、BackendServiceClientを使用して非同期リクエストを行うときに常に非同期レスポンスを受信するための非同期レスポンス・エンドポイントが公開されます。

4. Server1のClientWebAppはBackendServiceClient.doSomethingAsync()を呼び出して、バックエンド・サービスで操作を実行します。非同期レスポンス・エンドポイントのアドレスはReplyToアドレスに含まれます。このアドレスはクラスタのフロントエンドのアドレスで開始しており、Server1のアドレスではありません。

5. クラスタがdoSomething操作に対するレスポンスを受信します。

6. クラスタはメッセージをロード・バランシングし、今度はServer2にメッセージを送ります。

7. Server2にはレスポンスを受信するための非同期レスポンス・エンドポイントがないので、メッセージの配信は失敗します。

この問題を解決するには、次のどちらかを使用できます。

- SOAP対応のクラスタ・フロントエンド・プロキシ・プラグイン(WebLogic Server HttpClusterServletなど)を使用します。詳細は、『Oracle WebLogic Serverクラスタの使用』のプロキシ・プラグインの構成に関する項を参照してください。たとえばクラスタのフロントエンド・テクノロジが標準化されているような場合、この解決方法は使用できない場合があります。

- クラスタ内のすべてのメンバー・サーバーが非同期レスポンス・エンドポイントを公開して、非同期レスポンス・メッセージを任意のメンバー・サーバーに配信できるようにし、必要に応じてインプレース・クラスタ・ルーティングを介して正しいサーバーにメッセージを転送します。

第2の方法を実装するには、シングルトン・ポート・インスタンスを定義し、その初期化をクライアント・コンテナの初期化時(デプロイメント時)に行うことをお薦めします。クラスタの非同期レスポンス・エンドポイントの初期化のお薦めする方法の例については、例3-2「非同期Webサービス・クライアントのベスト・プラクティスの例」を参照してください。

注意:

コンテナの種類によっては、異なる方法でエンドポイントを初期化することもできます。たとえば、クライアントがWebサービスでホストされている場合、Webサービス・コンテナのメソッドに@PostConstructアノテーションを付けることができ、そのメソッドでシングルトン・ポートを初期化できます。EJBコンテナでは、シングルトン・ポートを作成するためのトリガー・ポイントとしてejbCreate()メソッドを使用できます。

5 信頼性のあるWebサービスとクライアントを開発する手順

この章では、Java API for XML Web Services(JAX-WS)用のWebLogic Webサービスとクライアントを開発するためのベスト・プラクティスについて説明します。

この章の内容は以下のとおりです。

- 信頼性のあるWebサービス・クライアントを開発する手順

- 信頼性のあるWebサービスを開発する手順

- ファイアウォールの内側から信頼性のあるWebサービスにアクセスする手順(接続作成)

- 信頼性のあるWebサービスを保護する手順

注意:

『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』で説明されているように、Webサービスとクライアントの開発に関する一般的な概念に習熟していることが前提となっています。

「Webサービス永続性を構成する手順」も参照してください。

信頼性のあるWebサービス・クライアントを開発する手順

表5-1では、信頼性のあるWebサービス・クライアントを開発するためのベスト・プラクティスとその例を示します。これらのガイドラインは、第3章「Webサービス・クライアントを開発する手順」で示されているガイドラインと併せて使用する必要があります。

表5-1 信頼性のあるWebサービス・クライアントを開発する手順

ベスト・プラクティス

説明

常に信頼性エラー・リスナーを実装します。

詳細は、「信頼性エラー・リスナーの実装」を参照してください。

メッセージを作業単位にグループ化します。

送信されるすべてのメッセージでRMシーケンスの作成と終了のプロトコル・オーバーヘッドを発生させるのではなく、メッセージをビジネス作業単位にグループ化できます(バッチ化とも呼ばれます)。詳細は、「ビジネス作業単位へのメッセージのグループ化(バッチ化)」を参照してください。

注意: このベスト・プラクティスは例5-1では示されていません。

確認応答の間隔を特定のシナリオに適した現実的な値に設定します。

お薦めする設定は、リクエスト間の通常の間隔の2倍です。詳細は、「確認応答の間隔の構成」を参照してください。

注意: このベスト・プラクティスは例5-1では示されていません。

基本の再送信間隔を特定のシナリオに適した現実的な値に設定します。

お薦めする設定は、確認レスポンスの間隔または通常のレスポンス時間のどちらか大きい方の2倍です。詳細は、「基本の再送信間隔の構成」を参照してください。

注意: このベスト・プラクティスは例5-1では示されていません。

タイムアウト(非アクティブおよび順序の有効期限)を特定のシナリオに適した現実的な値に設定します。

詳細は、「非アクティブ・タイムアウトの構成」および「順序の有効期限の構成」を参照してください。

注意: このベスト・プラクティスは例5-1では示されていません。

次の例では、信頼性のあるWebサービス・クライアントを開発するためのベスト・プラクティスを示します。

例5-1 信頼性のあるWebサービス・クライアントのベスト・プラクティスの例

import java.io.*;
import java.util.*;

import javax.servlet.*;
import javax.xml.bind.JAXBContext;
import javax.xml.ws.*;

import weblogic.jws.jaxws.client.ClientIdentityFeature;
import weblogic.jws.jaxws.client.async.AsyncClientHandlerFeature;
import weblogic.jws.jaxws.client.async.AsyncClientTransportFeature;
import weblogic.wsee.reliability2.api.ReliabilityErrorContext;
import weblogic.wsee.reliability2.api.ReliabilityErrorListener;
import weblogic.wsee.reliability2.api.WsrmClientInitFeature;

import com.sun.xml.ws.developer.JAXWSProperties;

/**
* Example client for invoking a reliable Web service asynchronously.
*/
public class BestPracticeAsyncRmClient
extends GenericServlet {

private BackendReliableServiceService _service;
private BackendReliableService _singletonPort;
private WebServiceFeature[] _features;

private static int _requestCount;
private static String _lastResponse;
private static final String MY_PROPERTY = "MyProperty";

@Override
public void init()
throws ServletException {

_requestCount = 0;
_lastResponse = null;

// Only create the Web service object once as it is expensive to create repeatedly.
if (_service == null) {
_service = new BackendReliableServiceService();
}

// Best Practice: Use a stored list of features, per client ID, to create client instances.
// Define all features for the Web service port, per client ID, so that they are
// consistent each time the port is called. For example:
// _service.getBackendServicePort(_features);

List<WebServiceFeature> features = new ArrayList<WebServiceFeature>();

// Best Practice: Explicitly define the client ID.
ClientIdentityFeature clientIdFeature =
new ClientIdentityFeature("MyBackendServiceAsyncRmClient");
features.add(clientIdFeature);

// Best Practice: Always implement a reliability error listener.
// Include this feature in your reusable feature list. This enables you to determine
// a reason for failure, for example, RM cannot deliver a request or the RM sequence fails in
// some way (for example, client credentials refused at service).
WsrmClientInitFeature rmFeature = new WsrmClientInitFeature();
features.add(rmFeature);
rmFeature.setErrorListener(new ReliabilityErrorListener() {
public void onReliabilityError(ReliabilityErrorContext context) {

// At a *minimum* do this
System.out.println("RM sequence failure: " +
context.getFaultSummaryMessage());
_lastResponse = context.getFaultSummaryMessage();

// And optionally do this...

// The context parameter conveys whether a request or the entire
// sequence has failed. If a sequence fails, you will get a notification
// for each undelivered request (if any) on the sequence.
if (context.isRequestSpecific()) {
// Single request failure (possibly as part of a larger sequence failure).
// Retrieve the original request.
String operationName = context.getOperationName();
System.out.println("Failed to deliver request for operation '" +
operationName + "'. Fault summary: " +
context.getFaultSummaryMessage());
if ("DoSomething".equals(operationName)) {
try {
String request = context.getRequest(JAXBContext.newInstance(),
String.class);
System.out.println("Failed to deliver request for operation '" +
operationName + "' with content: " +
request);
Map<String, Serializable> requestProps =
context.getUserRequestContextProperties();
if (requestProps != null) {
// Retrieve the request property. Use MyProperty
// to describe the request that failed and print this value
// during the simple 'error recovery' below.
String myProperty = (String)requestProps.get(MY_PROPERTY);
System.out.println("Got MyProperty value propagated from request: "+
myProperty);
System.out.println(myProperty + " failed!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
// The entire sequence has encountered an error.
System.out.println("Entire sequence failed: " +
context.getFaultSummaryMessage());

}
}
});

// Asynchronous endpoint.
AsyncClientTransportFeature asyncFeature =
new AsyncClientTransportFeature(getServletContext());
features.add(asyncFeature);

// Best Practice: Define a port-based asynchronous callback handler,
// AsyncClientHandlerFeature, for asynchronous and dispatch callback handling.
BackendReliableServiceAsyncHandler handler =
new BackendReliableServiceAsyncHandler() {
public void onDoSomethingResponse(Response<DoSomethingResponse> res) {
// ... Handle Response ...
try {
// Show getting the MyProperty value back.
DoSomethingResponse response = res.get();
_lastResponse = response.getReturn();
System.out.println("Got (reliable) async response: " + _lastResponse);
// Retrieve the request property. This property can be used to
// 'remember' the context of the request and subsequently process
// the response.
Map<String, Serializable> requestProps =
(Map<String, Serializable>)
res.getContext().get(JAXWSProperties.PERSISTENT_CONTEXT);
String myProperty = (String)requestProps.get(MY_PROPERTY);
System.out.println("Got MyProperty value propagated from request: "+
myProperty);
} catch (Exception e) {
_lastResponse = e.toString();
e.printStackTrace();
}
}
};
AsyncClientHandlerFeature handlerFeature =
new AsyncClientHandlerFeature(handler);
features.add(handlerFeature);

// Set the features used when creating clients with
// the client ID "MyBackendServiceAsyncRmClient."

_features = features.toArray(new WebServiceFeature[features.size()]);

// Best Practice: Define a singleton port instance and initialize it when
// the client container initializes (upon deployment).
// The singleton port will be available for the life of the servlet.
// Creation of the singleton port triggers the asynchronous response endpoint to be published
// and it will remain published until our container (Web application) is undeployed.
// Note, we will get a call to destroy() before this.
_singletonPort = _service.getBackendReliableServicePort(_features);
}

@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {

// TODO: ... Read the servlet request ...

// For this simple example, echo the _lastResponse captured from
// an asynchronous DoSomethingResponse response message.

if (_lastResponse != null) {
res.getWriter().write(_lastResponse);
_lastResponse = null; // Clear the response so we can get another
return;
}

// Set _lastResponse to NULL in order to make a new invocation against
// BackendService to generate a new response

// Best Practice: Synchronize use of client instances.
// Create another port using the *exact* same features used when creating _singletonPort.
// Note, this port uses the same client ID as the singleton port and it is effectively the
// same as the singleton from the perspective of the Web services runtime.
// This port will use the asynchronous response endpoint for the client ID,
// as it is defined in the _features list.
// NOTE: This is *DEFINITELY* not best practice or ideal because our application is
//       incurring the cost of an RM handshake and sequence termination
//       for *every* reliable request sent. It would be better to send
//       multiple requests on each sequence. If there is not a natural grouping
//       for messages (a business 'unit of work'), then you could batch
//       requests onto a sequence for efficiency. For more information, see
//        Grouping Messages into Business Units of Work (Batching).
BackendReliableService anotherPort =
_service.getBackendReliableServicePort(_features);

// Set the endpoint address for BackendService.
((BindingProvider)anotherPort).getRequestContext().
put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"http://localhost:7001/BestPracticeReliableService/BackendReliableService");

// Make the invocation. Our asynchronous handler implementation (set
// into the AsyncClientHandlerFeature above) receives the response.
String request = "Protect and serve";
System.out.println("Invoking DoSomething reliably/async with request: " +
request);
// Add a persistent context property that will be returned on the response.
// This property can be used to 'remember' the context of this
// request and subsequently process the response. This property will *not*
// get passed over wire, so the properties can change independent of the
// application message.
Map<String, Serializable> persistentContext =
(Map<String, Serializable>)((BindingProvider)anotherPort).
getRequestContext().get(JAXWSProperties.PERSISTENT_CONTEXT);
String myProperty = "Request " + (++_requestCount);
persistentContext.put(MY_PROPERTY, myProperty);
System.out.println("Request being made (reliably) with MyProperty value: " +
myProperty);
anotherPort.doSomethingAsync(request);

// Return a canned string indicating the response was not received
// synchronously. Client needs to invoke the servlet again to get
// the response.
res.getWriter().write("Waiting for response...");

// Best Practice: Explicitly close client instances when processing is complete.
// If not closed, the port will be closed automatically when it goes out of scope.
// This will force the termination of the RM sequence we created when sending the first
// doSomething request. For a better way to handle this, see
//  Grouping Messages into Business Units of Work (Batching).
// NOTE: Even though the port is closed explicitly (or even if it goes out of scope)
//       the reliable request sent above will still be delivered
//       under the scope of the client ID used. So, even if the service endpoint
//       is down, RM retries the request and delivers it when the service endpoint
//       available. The asynchronous resopnse will be delivered as if the port instance was
//       still available.
((java.io.Closeable)anotherPort).close();
}

@Override
public void destroy() {

try {
// Best Practice: Explicitly close client instances when processing is complete.
// Close the singleton port created during initialization. Note, the asynchronous
// response endpoint generated by creating _singletonPort *remains*
// published until our container (Web application) is undeployed.
((java.io.Closeable)_singletonPort).close();
// Upon return, the Web application is undeployed, and our asynchronous
// response endpoint is stopped (unpublished). At this point,
// the client ID used for _singletonPort will be unregistered and will no longer be
// visible from the Administration Console and WLST.
} catch (Exception e) {
e.printStackTrace();
}
}
}

信頼性のあるWebサービスを開発する手順

表5-2では、信頼性のあるWebサービスを開発するためのベスト・プラクティスを示します。ファイアウォールの内側から信頼性のあるWebサービスにアクセスするときのベスト・プラクティスについては、「ファイアウォールの内側から信頼性のあるWebサービスにアクセスする手順(接続作成)」を参照してください。

表5-2 信頼性のあるWebサービスを開発する手順

ベスト・プラクティス

説明

基本の再送信間隔を特定のシナリオに適した現実的な値に設定します。

詳細は、「基本の再送信間隔の構成」を参照してください。

確認応答の間隔を特定のシナリオに適した現実的な値に設定します。

お薦めする設定は、リクエスト間の通常の間隔の2倍です。詳細は、「確認応答の間隔の構成」を参照してください。

タイムアウト(非アクティブおよび順序の有効期限)を特定のシナリオに適した現実的な値に設定します。

以下のことを考慮してください。

- 非常に短期間の交換の場合、デフォルトのタイムアウトでは長すぎて、シーケンスの状態が必要以上に長く維持される場合があります。

- 特定のビジネス作業単位の予想される継続時間の2倍にタイムアウトを設定します。これにより、シーケンスは十分に長く存在できます。

詳細は、「非アクティブ・タイムアウトの構成」および「順序の有効期限の構成」を参照してください。

必要な最低の配信保証(またはサービス品質)を反映した信頼性のあるメッセージング・ポリシーを使用します。

デフォルトでは、配信保証はExactly Once, In Orderに設定されています。順序が必要ない場合、配信保証を単にExactly Onceに設定することで、パフォーマンスを向上させることができます。同様に、重複するリクエストをサービスが許容できる場合は、配信保証をAt Least Onceに設定できます。

信頼性のあるメッセージングの配信保証の詳細は、表6-1「信頼性のあるメッセージングの配信保証」および「Webサービスの信頼性のあるメッセージングのWS-Policyファイルの作成」を参照してください。

ファイアウォールの内側から信頼性のあるWebサービスにアクセスする手順(接続作成)

表5-3では、接続作成を使用してファイアウォールの内側から信頼性のあるWebサービスにアクセスするためのベスト・プラクティスを示します。これらのガイドラインは、「信頼性のあるWebサービスを開発する手順」および「非同期Webサービス・クライアントを開発する手順」で示されている一般的なガイドラインと組み合わせて使用する必要があります。

表5-3 ファイアウォールの内側から信頼性のあるWebサービスにアクセスする手順(接続作成)

ベスト・プラクティス

説明

信頼性のあるメッセージングの基本の再送信間隔で接続作成のポーリング間隔を調整します。

接続作成トランスポートに対して設定するポーリング間隔は、信頼性のあるメッセージング・プロトコルのメッセージがクライアントとサービスの間を往復するのに要する時間の下限を設定します。信頼性のあるメッセージングの基本の再送信間隔を接続作成ポーリング間隔に近い値に設定した場合、信頼性のあるメッセージングのリクエストがWebサービスによって受信され、信頼性のあるメッセージングのランタイムがリクエストの再送信を試みる前に関連するRM確認応答がリクエストに対して送信される(最善で1 接続作成ポーリング間隔後に)可能性が低くなります。信頼性のあるメッセージングの基本の再送信間隔を低すぎる値に設定すると、リクエストに対して不必要な再送信が発生し、重複する着信リクエストの処理が試みられて、接続作成がリクエストからレスポンスを取得するためにメッセージをポーリングするため、サービス側で負荷が連鎖的に発生する可能性があります。

基本の再送信間隔は接続作成ポーリング間隔の2倍以上の値に設定することをお薦めします。

注意: Webサービスの信頼性のあるメッセージングと接続作成を併用すると、接続作成のポーリング間隔が必要に応じて実行時に調整され、信頼性のあるメッセージングの基本の再送信間隔より少なくとも3秒小さい値に設定されます。基本の再送信間隔が3秒以下の場合は、接続作成のポーリング間隔は基本の再送信間隔の値に設定されます。

接続作成のポーリング間隔と信頼性のあるメッセージングの基本の再送信間隔の設定の詳細は、それぞれ、「ポーリング間隔の構成」および「基本の再送信間隔の構成」を参照してください。

信頼性のあるWebサービスを保護する手順

表5-4では、WS-SecureConversationを使用して信頼性のあるWebサービスを保護するためのベスト・プラクティスを示します。これらのガイドラインは、「信頼性のあるWebサービスを開発する手順」で示されているガイドラインと併せて使用する必要があります。

表5-4 信頼性のあるWebサービスを保護する手順

ベスト・プラクティス

説明

信頼性のあるメッセージングの基本の再送信間隔および確認応答の間隔でWS-SecureConversationの存続期間を調整します。

信頼性のあるメッセージングの基本の再送信間隔および確認応答の間隔に近い値、またはそれより小さい値に、WS-SecureConversationの存続期間を設定すると、信頼性のあるメッセージングのハンドシェイク・メッセージをWebサービスに送信できる前に、WS-SecureConversationトークンの有効期限が切れる可能性があります。このため、WS-SecureConversationの存続期間は、基本の再送信間隔の2倍以上に設定することをお薦めします。

基本の再送信間隔の設定の詳細は、「基本の再送信間隔の構成」を参照してください。

6 Webサービスの信頼性のあるメッセージングの使用

この章では、Java API for XML Web Services(JAX-WS)を使用するWebLogic Webサービスで、Webサービスの信頼性のあるメッセージング(WS-ReliableMessaging)を使用する方法について説明します。

「信頼性のあるWebサービスとクライアントを開発する手順」も参照してください。

この章の内容は以下のとおりです。

- Webサービスの信頼性のあるメッセージングの概要

- 信頼性のあるWebサービスの作成および呼出し手順

- 送信元と宛先のWebLogic Serverインスタンスの構成

- Webサービスの信頼性のあるメッセージングのWS-Policyファイルの作成

- 信頼性のあるJWSファイルに関するプログラミングのガイドライン

- Webサービス・クライアントからの信頼性のあるWebサービスの呼出し

- 信頼性のあるメッセージングの構成

- 信頼性エラー・リスナーの実装

- 信頼性のあるメッセージ・シーケンスのライフサイクルの管理

- Webサービスの信頼性のあるメッセージングの監視

- ビジネス作業単位へのメッセージのグループ化(バッチ化)

- 信頼性のあるWebサービスを再デプロイする際にクライアント側で考慮すべき事項

- WebLogic Web サービスの信頼性のあるメッセージングとの相互運用性

WebLogic Serverのサンプル・サーバーには、信頼性のあるメッセージングに関する次の3つのサンプルが含まれています。

- JAX-WS Webサービスでの信頼性のあるメッセージングの構成

- JAX-WS Webサービスでの接続作成および信頼性のあるメッセージングの使用

- JAX-WS Webサービスでの保護された信頼性のあるメッセージングの構成

詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebLogic Server配布キットのWebサービス・サンプルに関する項を参照してください。

Webサービスの信頼性のあるメッセージングの概要

Webサービスの信頼性のあるメッセージングとは、ある1つのアプリケーション・サーバーで実行中のアプリケーションが、別のアプリケーション・サーバーで実行中のWebサービスを確実に呼び出せるフレームワークです。ここでは、双方のサーバーでWS-ReliableMessaging仕様が実装されていることが前提となっています。信頼性が高いとは、ソフトウェア・コンポーネント、システム、またはネットワークの障害があっても、2つのエンドポイント(Webサービスとクライアント)間でメッセージ配信を保証することができる状態として定義されます。

WebLogic Webサービスは、WS-ReliableMessaging 1.2仕様(2009年2月)(http://docs.oasis-open.org/ws-rx/wsrm/200702)に準拠しています(また、バージョン1.1をサポートしています)。この仕様では、異なるアプリケーション・サーバー上の2つのエンドポイント(Webサービスとクライアント)が確実に通信できる方法について記述されています。具体的には、この仕様では送信元エンドポイント(つまりクライアントWebサービス)から宛先エンドポイント(つまり操作を確実に呼び出せるWebサービス)へ送信されるメッセージが、1つ以上の配信保証に基づいて確実に配信されるか、そうでなければ必ずエラーが発生する、相互運用性を備えたプロトコルについて説明されています。

信頼性のあるWebLogic Webサービスには、次の配信保証が備わっています。

表6-1 信頼性のあるメッセージングの配信保証

配信保証

説明

At Most Once

メッセージは最大で1回、重複なしに配信されます。メッセージによっては、一度も配信されない可能性もあります。

At Least Once

すべてのメッセージが、少なくとも1回配信されます。メッセージによっては、1回よりも多く配信される可能性があります。

Exactly Once

すべてのメッセージが、必ず1回重複なしに配信されます。

In Order

メッセージは、送信された順序で配信されます。この配信保証は、上記の3つの保証と組み合わせることもできます。

次の項では、信頼性のあるWebサービスとクライアントの作成方法、およびWebサービスをデプロイするWebLogic Serverインスタンスの構成方法について説明します。

WS-Policyを使用した信頼性のあるメッセージング・ポリシーのアサーションの指定

WebLogic Webサービスでは、宛先エンドポイントがWebサービスの信頼性のあるメッセージングの機能と要件を記述および公開できるように、WS-Policyファイルを使用します。WS-Policyファイルは、サポートされているWS-ReliableMessaging仕様のバージョンやサービス品質の要件などが記述されたXMLファイルです。WS-Policy仕様(http://www.w3.org/TR/ws-policy/)では、Webサービスのポリシーを記述して通信するための、汎用的なモデルと構文が提供されています。

WebLogic Serverには、標準的な信頼性のあるメッセージング・アサーションを含むあらかじめパッケージ化されているWS-Policyファイルがあります。「Webサービスの信頼性のあるメッセージングと接続作成のためのあらかじめパッケージ化されたWS-Policyファイル」を参照してください。あらかじめパッケージ化されているWS-Policyファイルがニーズに合わない場合は、独自のWS-Policyファイルを作成する必要があります。詳細は、「Webサービスの信頼性のあるメッセージングのWS-Policyファイルの作成」を参照してください。信頼性のあるメッセージングのポリシー・アサーションに関するリファレンス情報は、『Oracle WebLogic Server WebLogic Webサービス・リファレンス』のWebサービスの信頼性のあるメッセージングのポリシー・アサーションに関するリファレンスの項を参照してください。

信頼性のあるメッセージングでサポートされるトランスポート・タイプ

Webサービスの信頼性のあるメッセージングは、非同期的または同期的に使用できます。メッセージを非同期に配信するときは、必要に応じて、メッセージ配信の自動再試行をサポートするようにバッファリングを構成できます。

次の表では、Webサービスの信頼性のあるメッセージングに対するトランスポート・タイプのサポートを示します。Webサービス・クライアントのトランスポート・タイプのサポートの詳細は、「Webサービス・クライアントからの信頼性のあるWebサービスの呼出し」を参照してください。障害リカバリの詳細は、「信頼性のあるメッセージングの障害リカバリのシナリオ」を参照してください。

注意:

メッセージ・バッファリングは、Webサービスに対して構成できます。詳細は、第8章「Webサービスのためのメッセージ・バッファリングの構成」を参照してください。Webサービス・クライアントの場合、メッセージ・バッファリングはデフォルトで有効化されています。

表6-2 Webサービスの信頼性のあるメッセージングのトランスポート・タイプ

トランスポート・タイプ

特長

非同期トランスポート

バッファ付きWebサービスの場合:

- 最も堅牢な使用モードですが、最も多くのオーバーヘッドを必要とします。

- メッセージ配信を自動的に再試行します。

- ネットワークが停止しても維持されます。

- 送信元エンドポイントまたは宛先エンドポイントを再起動できます。

- 非匿名ReplyToを使用します。

- 非同期クライアント・トランスポートを使用すると、1つのスレッドで複数のリクエストを処理でき、負荷をいっそう効率よく緩和できます。詳細は、「スケーラブルな非同期JAX-WSクライアントの開発(非同期クライアント・トランスポート)」を参照してください。

- Webサービス・クライアントは、非同期または同期の呼出しセマンティクスを使用して、Webサービスを呼び出すことができます。詳細は、表4-1「非同期Webサービス呼出しのサポート」を参照してください。

非バッファWebサービスの場合:

- 非同期のバッファ付き使用モードよりオーバーヘッドが少なくなります。

- 順序の状態のみが保持されます。

- 非匿名ReplyToを使用します。

- Webサービス・クライアントは、非同期または同期の呼出しセマンティクスを使用して、Webサービスを呼び出すことができます。詳細は、表4-1「非同期Webサービス呼出しのサポート」を参照してください。

同期トランスポート

- オーバーヘッドは最も少なく、最も簡単なプログラミング・モデルです。

- 匿名ReplyToを使用します。

- Webサービス・クライアントは、非同期または同期の呼出しセマンティクスを使用して、Webサービスを呼び出すことができます。詳細は、表4-1「非同期Webサービス呼出しのサポート」を参照してください。

- Webサービス・クライアントが同期トランスポートを使用してバッファ付きWebサービスを呼び出した場合、結果は次のいずれかになります。
- シーケンスの最初のリクエストの場合、宛先のシーケンスはバッファなしに設定されます(Webサービスの構成がバッファなしとして設定されていた場合と同様)

- シーケンスの最初のリクエストではない場合は(つまり、クライアントが前に非同期トランスポートを使用してリクエストを送信していた場合)、リクエストは破棄されてエラーが返されます。

信頼性のあるメッセージ・シーケンスのライフサイクル

次の図に、信頼性のあるメッセージの一方向の交換を示します。

図6-1 Webサービスの信頼性のあるメッセージの交換

「図6-1 Webサービスの信頼性のあるメッセージの交換」の説明

信頼性のあるメッセージ・シーケンスは、RM送信元とRM宛先の間で確実に交換されるメッセージ・セットの進捗状況を追跡する際に使用されます。シーケンスは、0個以上のメッセージの送信に使用でき、文字列識別子で識別されます。この識別子は、信頼性のあるメッセージングを使用する際に、そのシーケンスを参照するために使用されます。

Webサービス・クライアント・アプリケーションは、RM送信元がRM宛先へ送信する信頼性のある配信のメッセージを送信します。RM宛先は、信頼性のあるメッセージを受信したことを確認応答し、そのメッセージをWebサービス・アプリケーションに配信します。RM送信元は、確認応答を受け取るまでメッセージを再送信できます。RM宛先は、リクエストをバッファリングするように構成されている場合は、Webサービスがリクエストの処理に失敗すると、Webサービスにリクエストを再配信できます。

Webサービス・クライアントは、クライアント・インスタンス(ポート・インスタンスまたはディスパッチ・インスタンス)でメソッドを呼び出して、ターゲットWebサービスにメッセージを送信します。ポートは、ポート・タイプの信頼性のあるWebサービスと関連付けられていて、そのサービスに対するプログラム・インタフェースを表します。ポートは、jwsc Antタスクの<clientgen子要素で作成されます。ディスパッチ・インスタンスはクライアントからWebサービスにメッセージ全体を配信するための、緩やかに型指定された汎用インタフェースです。ディスパッチ・クライアントの詳細は、「Webサービス・ディスパッチ・クライアントの開発」を参照してください。

WebLogicでは、このクライアント・インスタンス内に、信頼性のあるメッセージ・シーケンスの識別子が格納されます。これによって、信頼性のあるメッセージ・シーケンスが単一のクライアント・インスタンスに接続されます。特定のクライアント・インスタンスを使用して送信されるすべてのメッセージは、その送信メッセージ数に関係なく、同じ信頼性のあるメッセージ・シーケンスを使用します。(バッチ化を使用しない場合は、「ビジネス作業単位へのメッセージのグループ化(バッチ化)」を参照してください。)

WebLogic Serverには、信頼性のあるシーケンスに関連付けられたリソースが保持されるため、タイミングよくリソースを解放する手順を踏むことをお薦めします。この手順は、クライアント・インスタンス自体のライフサイクルを管理するか、またはweblogic.wsee.reliability2.api.WsrmClient APIを使用して実行できます。WsrmClient APIを使用すると、構成オプションの設定、シーケンスIDの取得、信頼性のあるシーケンスの終了といった一般的なタスクを実行できます。詳細は、「信頼性のあるメッセージ・シーケンスのライフサイクルの管理」を参照してください。

信頼性のあるメッセージングの障害リカバリのシナリオ

次の項では、さまざまなシナリオでの信頼性のあるメッセージングの障害リカバリの概要について説明します。

- リクエストが到着する前にRM宛先がダウンする

- リクエストが行われた後でRM送信元がダウンする

- リクエストが到着した後でRM宛先がダウンする

- バッファなしの信頼性のあるWebサービスでの障害シナリオ

最初の3つのシナリオでは、Webサービスとクライアントの両方でバッファリングが有効であるものとします。最後のシナリオでは、バッファなしのWebサービスでの信頼性のあるメッセージングの障害リカバリについて説明します。バッファリングは、Webサービス・クライアントではデフォルトで有効になります。Webサービスでのバッファリングの構成の詳細は、第8章「Webサービスのためのメッセージ・バッファリングの構成」を参照してください。

リクエストが到着する前にRM宛先がダウンする

表6-3では、RM送信元からのリクエストが到着する前にRM宛先が使用できなくなったときの、信頼性のあるメッセージングの障害リカバリ・シナリオについて説明します。

Webサービスとクライアントの両方でWebサービス・バッファリングが有効であるものとします。バッファリングは、Webサービス・クライアントではデフォルトで有効になります。Webサービスでのバッファリングの構成の詳細は、第8章「Webサービスのためのメッセージ・バッファリングの構成」を参照してください。

表6-3 信頼性のあるメッセージングの障害リカバリのシナリオ: リクエストが到着する前にRM宛先がダウンする

トランスポート・タイプ

シナリオの説明

非同期トランスポート

1. クライアントが非同期メソッドを呼び出します。

2. 信頼性のあるメッセージングのランタイムがリクエストを受け付けます。クライアントは他の作業に戻ります。

3. 信頼性のあるメッセージングのランタイムはリクエストの配信を試みますが、RM宛先がダウンしているため失敗します。

4. 信頼性のあるメッセージングのランタイムは再試行間隔だけ待ってから、リクエストの送信を再び試みます。リクエストの配信は再び失敗します。

5. RM宛先が起動します。

6. 信頼性のあるメッセージングのランタイムは再試行間隔だけ待ってから、リクエストの送信を再び試みます。リクエストの配信が成功します。

7. リクエストのメッセージ番号を含む確認応答が、クライアントに送信されます。信頼性のあるメッセージングのランタイムは再試行リストからメッセージを削除します。

8. レスポンスが到着し、クライアントはそれを処理します。

注意: 「信頼性のあるメッセージ・シーケンスのライフサイクルの管理」で説明されているように、クライアントはいつでも、確認応答のステータスを確認したり、メッセージについての情報にアクセスしたりできます。

同期トランスポート

1. クライアントが同期メソッドを呼び出します。

2. 信頼性のあるメッセージングのランタイムはリクエストを受け付け、クライアントのスレッドをブロックします。

3. 信頼性のあるメッセージングのランタイムはリクエストの配信を試みますが、RM宛先がダウンしているため失敗します。

4. 信頼性のあるメッセージングのランタイムは再試行間隔だけ待ってから、リクエストの送信を再び試みます。リクエストの配信は再び失敗します。

5. RM宛先が起動します。

6. 信頼性のあるメッセージングのランタイムは再試行間隔だけ待ってから、リクエストの送信を再び試みます。リクエストの配信が成功します。

7. レスポンスと確認応答は、トランスポート戻りチャネルを通してクライアントに送信されます。確認応答には、リクエストのメッセージ番号が含まれます。信頼性のあるメッセージングのランタイムは再試行リストからメッセージを削除します。

8. 信頼性のあるメッセージングのランタイムはクライアント・スレッドのブロックを解除し、レスポンスを返します。

9. クライアントは、メソッド呼出しの戻り値としてレスポンスを受け取り、レスポンスを処理します。

注意: 「信頼性のあるメッセージ・シーケンスのライフサイクルの管理」で説明されているように、クライアントはいつでも、確認応答のステータスを確認したり、メッセージについての情報にアクセスしたりできます。

注意: 同期トランスポートで真の信頼性を実現するには、接続作成を使用することをお薦めします。詳細は、「ファイアウォールの内側からの非同期Webサービス・クライアントの使用(接続作成)」を参照してください。

リクエストが行われた後でRM送信元がダウンする

表6-4では、リクエストを行った後でRM送信元がダウンするときの、信頼性のあるメッセージングの障害リカバリ・シナリオについて説明します。

Webサービスとクライアントの両方でWebサービス・バッファリングが有効であるものとします。バッファリングは、Webサービス・クライアントではデフォルトで有効になります。Webサービスでのバッファリングの構成の詳細は、第8章「Webサービスのためのメッセージ・バッファリングの構成」を参照してください。

表6-4 信頼性のあるメッセージングの障害リカバリのシナリオ: リクエストを行った後でRM送信元がダウンする

トランスポート・タイプ

シナリオの説明

非同期トランスポート

1. クライアントが非同期メソッドを呼び出します。

2. 信頼性のあるメッセージングのランタイムがリクエストを受け付けます。クライアントは他の作業に戻ります。

3. クライアント(RM送信元)がダウンします。

4. クライアントが起動します。クライアントは、同じクライアントIDを使用してクライアント・インスタンスを初期化する必要があります。ランタイムは、このクライアントIDを使用して、クライアントに対してアクティブであった信頼性のあるシーケンスIDを取得します。詳細は、「クライアントIDの管理」を参照してください。

5. 信頼性のあるメッセージングのランタイムは、クライアントがダウンする前に使用中であった信頼性のあるシーケンスIDを検出し、受け付けたリクエストを回復します。
注意: リクエストの配信はクライアント・インスタンスによって提供されたリソースに依存するので、この手順は、リクエストの送信に使用されたクライアント・インスタンスをクライアントが再初期化した後でのみ実行されます。クライアントでは、静的ブロック内でクライアント・インスタンスを初期化するか、@PostConstructアノテーションを使用するか、クライアント・インスタンスの早い初期化が保証される他のメカニズムを使用することをお薦めします。詳細は、「Webサービス・クライアントを開発する手順」で示されているベスト・プラクティスの例を参照してください。

6. 信頼性のあるメッセージングのランタイムがリクエストを送信し、成功します。

7. リクエストのメッセージ番号を含む確認応答が、クライアントに送信されます。信頼性のあるメッセージングのランタイムは再試行リストからメッセージを削除します。

8. レスポンスが到着し、クライアントはそれを処理します。

注意: 「信頼性のあるメッセージ・シーケンスのライフサイクルの管理」で説明されているように、クライアントはいつでも、確認応答のステータスを確認したり、メッセージについての情報にアクセスしたりできます。

同期トランスポート

1. クライアントが同期メソッドを呼び出します。

2. 信頼性のあるメッセージングのランタイムはリクエストを受け付け、クライアントのスレッドをブロックします。

3. 信頼性のあるメッセージングのランタイムがリクエストの配信を試みます。リクエストの配信が成功します。

4. レスポンスを送信できる前に、クライアント(RM送信元)がダウンします。VMが終了するので、クライアント・スレッドが、呼出し状態およびクライアント自体の呼出しスタックと共に失われます。

5. クライアント(RM送信元)が起動します。クライアントは、同じクライアントIDを使用してクライアント・インスタンス(ポートまたはディスパッチ)を再初期化します。詳細は、「クライアントIDの管理」を参照してください。

6. 信頼性のあるメッセージングのランタイムは、クライアントの以前のシーケンスIDを検出し、最後のリクエストが同期的に行われたことを確認します。

7. 信頼性のあるメッセージングのランタイムは、そのリクエストに対して永久的障害通知を配信し、クライアント・インスタンスと関連付けられているRMシーケンス全体を失敗させます。クライアント・インスタンスと関連付けられているすべてのReliabilityErrorListenerが、この時点で呼び出されます。

8. クライアントは、元のリクエストを取得し(何らかのクライアント固有のメカニズムを使用して)、リクエストでクライアント・インスタンスを再度呼び出してリクエストを再送信します。

注意: 「信頼性のあるメッセージ・シーケンスのライフサイクルの管理」で説明されているように、クライアントはいつでも、確認応答のステータスを確認したり、メッセージについての情報にアクセスしたりできます。

注意: 同期トランスポートで真の信頼性を実現するには、接続作成を使用することをお薦めします。詳細は、「ファイアウォールの内側からの非同期Webサービス・クライアントの使用(接続作成)」を参照してください。

リクエストが到着した後でRM宛先がダウンする

表6-5では、RM送信元からのリクエストを受け付けた後でRM宛先が使用できなくなったときの、信頼性のあるメッセージングの障害リカバリ・シナリオについて説明します。

Webサービスとクライアントの両方でWebサービス・バッファリングが有効であるものとします。バッファリングは、Webサービス・クライアントではデフォルトで有効になります。Webサービスでのバッファリングの構成の詳細は、第8章「Webサービスのためのメッセージ・バッファリングの構成」を参照してください。

表6-5 信頼性のあるメッセージングの障害リカバリのシナリオ: リクエストが到着した後でRM宛先がダウンする

トランスポート・タイプ

シナリオの説明

非同期トランスポート

1. クライアントが非同期メソッドを呼び出します。

2. 信頼性のあるメッセージングのランタイムがリクエストを受け付けます。クライアントは他の作業に戻ります。

3. 信頼性のあるメッセージングのランタイムがリクエストの配信を試み、成功します。

4. RM宛先はリクエストを受け付けて、戻りチャネルで確認応答を送信します。

5. 信頼性のあるメッセージングのランタイムは確認応答を受け取り、再試行リストからメッセージを削除します。

6. RM宛先がダウンします。

7. RM送信元の信頼性のあるメッセージングのランタイムは、この間に保留中のリクエストを再試行します。

8. RM宛先が起動します。

9. RM宛先は格納されているリクエストを回復し、処理して、レスポンスを送信します。

10. レスポンスが到着し、クライアントはそれを処理します。

注意: 「信頼性のあるメッセージ・シーケンスのライフサイクルの管理」で説明されているように、クライアントはいつでも、確認応答のステータスを確認したり、メッセージについての情報にアクセスしたりできます。

同期トランスポート

注意: 同期トランスポートを使用してバッファ付きWebサービスを呼び出そうとした場合、結果は次のいずれかになります。

- シーケンスの最初のリクエストの場合、宛先のシーケンスはバッファなしに設定されます(Webサービスの構成がバッファなしとして設定されていた場合と同様)。

- シーケンスの最初のリクエストではない場合は(つまり、クライアントが前に非同期トランスポートを使用してリクエストを送信していた場合)、リクエストは破棄されてエラーが返されます。

次にこのシナリオのシーケンスを説明します。

1. クライアントが同期メソッドを呼び出します。

2. 信頼性のあるメッセージングのランタイムはリクエストを受け付け、クライアントのスレッドをブロックします。

3. 信頼性のあるメッセージングのランタイムがリクエストの配信を試みます。リクエストの配信が成功します。

4. RM宛先はリクエストを受け付けて、トランスポート戻りチャネルで確認応答を送信します。

5. クライアント(RM送信元)は確認応答を検出し、再試行リストからリクエストを削除します。

6. RM宛先がダウンします。

7. クライアント・スレッドはブロックされたままになります。

8. RM宛先が起動して回復し、リクエストを処理して、クライアントにレスポンスを送信します。

9. 信頼性のあるメッセージングのランタイムはクライアント・スレッドのブロックを解除し、レスポンスを返します。

10. クライアントは、メソッド呼出しの戻り値としてレスポンスを受け取り、レスポンスを処理します。

注意: 「信頼性のあるメッセージ・シーケンスのライフサイクルの管理」で説明されているように、クライアントはいつでも、確認応答のステータスを確認したり、メッセージについての情報にアクセスしたりできます。

バッファなしの信頼性のあるWebサービスでの障害シナリオ

バッファなしWebサービスの動作はバッファ付きWebサービスとは異なり、リクエストの確認応答と処理を行う前に、強化されたストレージに要求をバッファリングしません。バッファなしWebサービスはサービス・ロジックが失敗した場合でもリクエストを再処理しませんが、バッファ付きWebサービスはリクエストを再処理します。どちらの場合も、Webサービスによって生成されるすべてのレスポンスは、クライアントに返送される前にバッファリングされます。

バッファなしWebサービスは、次の場合に有効である場合があります。

- Webサービスが非トランザクション・リソースに対して動作しており、リクエストを2回以上処理する必要がない場合(バッファリングされたリクエストをデキューしたトランザクションのロールバックでは、非トランザクション・サービスの二次的影響をロールバックできないため)。

- Webサービスが比較的軽量であり、リクエストの処理に時間がかからない場合。

- Webサービスではパフォーマンスが最も重要であり、リクエストまたはレスポンスを失ってもかまわない場合。バッファなしWebサービスではリクエストをストアにバッファリングするオーバーヘッドがないため、バッファ付きWebサービスよりスループットがよくなります。パフォーマンスの向上は、リクエストをバッファリングするために必要な時間とリソースによって異なります(たとえば、非常に大きいリクエスト・メッセージでは、バッファリングに多くの時間とリソースが必要な場合があります)。

ほとんどの障害シナリオでは、バッファなしWebサービスの動作はバッファ付きWebサービスとほぼ同じです。例外は、サービス(RM宛先)自体で障害が発生した場合です。たとえば、説明したすべてのRM送信元障害シナリオでは、動作はバッファ付きWebサービスでもバッファなしWebサービス(RM宛先)でも同じです。バッファなしWebサービスでは、次の2つのポイントの間で障害ウィンドウが開きます。

- リクエストが処理のために受け付けられます。

- Webサービスからのレスポンスがクライアント(RMリソース)への配信のために登録されます。

これら2つのポイントの間でWebサービス(RM宛先)に障害が起きると、RM送信元はリクエストが正常に処理されたものと判断しますが(確認応答を受け取ったため)、レスポンスを受け取ることはなく、リクエストが処理されない可能性があります。

Webサービスをバッファなしとして実行するように構成する前に、この障害ウィンドウをよく検討してください。

信頼性のあるWebサービスの作成および呼出し手順

WebLogic Webサービスの信頼性のあるメッセージングを構成するには、JMSサーバーやストア・アンド・フォワード(SAF)・エージェントの作成など標準的なJMSタスクとともに、JWSファイルへのJWSアノテーションの追加などWebサービス固有のタスクを実行する必要があります。また、あらかじめパッケージ化されているファイルを使用しない場合は、必要に応じて、信頼性のあるWebサービスの信頼性のあるメッセージング機能を記述したカスタムWS-Policyファイルをユーザー側で作成します。

信頼性のあるWebサービスの呼出しにWebLogicクライアントAPIを使用している場合、クライアント・アプリケーションはWebLogic Server上で実行される必要があります。したがって構成タスクを、Webサービス・クライアントのコードがデプロイされる送信元WebLogic Serverインスタンスと、信頼性のあるWebサービスそのものがデプロイされる宛先WebLogic Serverインスタンスの双方で実行する必要があります。

表6-6は、信頼性のあるWebサービスと、その操作を呼び出すクライアントを作成する手順を説明しています。この手順では、Webサービスとクライアントを実装するJWSファイルをゼロから作成する方法を示しています。既存のJWSファイルを更新する場合は、この手順をガイドとして利用してください。またこの手順では、ソースWebLogic Serverインスタンスと宛先WebLogic Serverインスタンスの構成方法も示しています。

以下の作業を完了している必要があります。

- 宛先と送信元のWebLogic Serverインスタンスを作成しておきます。信頼性のあるWebサービスを宛先WebLogic Serverインスタンスにデプロイし、信頼性のあるWebサービスを呼び出すクライアントを送信元WebLogic Serverインスタンスにデプロイします。

- Antベースの開発環境を設定しておきます。

- 編集(jwsc Antタスクを実行して信頼性のある生成済Webサービスをデプロイするためのターゲットの追加など)が可能な作業用のbuild.xmlファイルの用意。

詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebLogic Webサービスの開発に関する項を参照してください。非同期の信頼性のあるWebサービスとクライアントの開発のベスト・プラクティスは、「信頼性のあるWebサービスとクライアントを開発する手順」を参照してください。

表6-6 信頼性のあるWebサービスの作成および呼出し手順

#

手順

説明

1

宛先WebLogic ServerインスタンスとソースWebLogic Serverインスタンスを構成します。

信頼性のあるWebサービスを宛先WebLogic Serverインスタンスにデプロイし、信頼性のあるWebサービスを呼び出すクライアントを送信元WebLogic Serverインスタンスにデプロイします。宛先WebLogic Serverインスタンスの構成の詳細は、「送信元と宛先のWebLogic Serverインスタンスの構成」を参照してください。

2

WS-Policyファイルを作成する(オプション)

任意のXMLまたはプレーン・テキスト・エディタを使用し、必要に応じて宛先WebLogic Server上で実行されているWebサービスの信頼性のあるメッセージング機能が記述されたWS-Policyファイルを作成します。独自のWS-Policyファイルを作成する方法の詳細は、「Webサービスの信頼性のあるメッセージングのWS-Policyファイルの作成」を参照してください。

注意: WebLogic Serverに付属しているいずれかのWS-Policyファイルを使用する場合、この手順は不要です。詳細は、付録A「Web Services Reliable Messagingと接続作成のためのあらかじめパッケージ化されたWS-Policyファイル」を参照を参照してください。

3

信頼性のあるWebサービスを実装するJWSファイルを作成および更新します。

このWebサービスは、宛先WebLogic Serverインスタンスにデプロイされます。「信頼性のあるJWSファイルに関するプログラミングのガイドライン」を参照してください。

たとえばベスト・プラクティスについては、「信頼性のあるWebサービスとクライアントを開発する手順」を参照してください。

4

信頼性のあるWebサービスのコンパイルに使用されるbuild.xmlファイルを更新します。

build.xmlファイルを更新して、信頼性のあるJWSファイルをWebサービスにコンパイルするjwsc Antタスクの呼出しを含めます。

jwscタスクの使用に関する一般情報は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のjwsc WebLogic WebサービスAntタスクの実行に関する項を参照してください。

5

信頼性のあるJWSファイルをコンパイルおよびデプロイします。

適切なターゲットを呼び出して信頼性のあるJWSファイルをコンパイルし、宛先WebLogic Serverにデプロイします。例:

prompt> ant build-reliableService deploy-reliableService

6

Webサービス・クライアントを作成または更新します。

Webサービス・クライアントは、信頼性のあるWebサービスを呼び出し、送信元WebLogic Serverにデプロイされます。「Webサービス・クライアントからの信頼性のあるWebサービスの呼出し」を参照してください。

7

信頼性のあるメッセージングを構成します。(オプション)

管理コンソールを使用して信頼性のあるWebサービスに対する信頼性のあるメッセージングを構成します。信頼性のあるWebサービスにアタッチされているWS-Policyファイルが、初期構成の設定を提供します。「信頼性のあるメッセージングの構成」を参照してください。

8

信頼性エラー・リスナーを実装します。(オプション)

信頼性のある配信が失敗した場合に通知を受け取る信頼性エラー・リスナーを実装します。「信頼性エラー・リスナーの実装」を参照してください。

9

信頼性のあるメッセージ・シーケンスのライフサイクルを管理します。(オプション)

WebLogic Serverでは、Webサービスの信頼性のあるメッセージングで使用するためのクライアントAPI weblogic.wsee.reliability2.api.WsrmClientが提供されています。このAPIを使用して、構成オプションの設定、信頼性のあるシーケンスIDの取得、信頼性のあるシーケンスの終了などの一般的なライフサイクル・タスクを実行します。詳細は、「信頼性のあるメッセージ・シーケンスのライフサイクルの管理」を参照してください。

10

クライアントWebサービスのコンパイルに使用されるbuild.xmlファイルを更新します。

build.xmlファイルを更新して、信頼性のあるJWSファイルをWebサービスにコンパイルするjwsc Antタスクの呼出しを含めます。

jwscタスクの使用に関する一般情報は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のjwsc WebLogic WebサービスAntタスクの実行に関する項を参照してください。

11

Webサービス・クライアント・ファイルをコンパイルしてデプロイします。

適切なターゲットを呼び出してクライアント・ファイルをコンパイルし、ソースWebLogic Serverにデプロイします。例:

prompt> ant build-clientService deploy-clientService

12

Webサービスの信頼性のあるメッセージングを監視します。

管理コンソールを使用して、Webサービスの信頼性のあるメッセージングを監視します。「Webサービスの信頼性のあるメッセージングの監視」を参照してください。

以降の項では、これらの各手順について詳細に説明します。さらに、次のトピックについて説明します。

- ビジネス作業単位へのメッセージのグループ化(バッチ化): メッセージをビジネス作業単位にグループ化し(バッチ化とも呼ばれます)、信頼性のあるメッセージングを使用するときのパフォーマンスを向上させます。

- 信頼性のあるWebサービスを再デプロイする際にクライアント側で考慮すべき事項: 信頼性のある更新済WebLogic Webサービスの新しいバージョンを、同じWebサービスの古いバージョンと一緒にデプロイする際に、クライアント側で考慮すべき事項について説明します。

- WebLogic Webサービスの信頼性のあるメッセージングとの相互運用性: WebLogic Webサービスの信頼性のあるメッセージングと相互運用するための推奨事項を示します。

送信元と宛先のWebLogic Serverインスタンスの構成

送信元と宛先のWebLogic Serverインスタンスに、Webサービスの永続性を構成する必要があります。信頼性のあるWebサービスを宛先WebLogic Serverインスタンスにデプロイし、信頼性のあるWebサービスを呼び出すクライアントを送信元WebLogic Serverインスタンスにデプロイします。

Webサービスの信頼性のあるメッセージングを使用するときは、状態が変化するたびに、Webサービスの信頼性のあるメッセージング・シーケンスがWebサービスの永続ストアに保存されます。状態変化の例を次に示します。

- 信頼性のあるメッセージングの状態が更新された(作成中、作成済み、終了中、終了済みなど)。

- セキュリティ・プロパティが更新された(セキュリティ・コンテキスト・トークンなど)。

- 信頼性のあるメッセージング・シーケンスでメッセージが送信された(メッセージ・バッファリングが有効の場合)。

- メッセージが到着したときに確認応答。

構成ウィザードでWebサービス固有の拡張テンプレートを使用してWebLogic Serverドメインを拡張することにより、Webサービスの永続性を構成できます。あるいは、Oracle WebLogic管理コンソールまたはWLSTを使用して、これらの高度な機能に必要なリソースを構成できます。Webサービス永続性の構成の詳細は、「Webサービス永続性の構成」を参照してください。

Webサービスにバッファリングを構成することもできます。メッセージ・バッファリングの構成に関する考慮事項と手順は、「第8章「Webサービスのためのメッセージ・バッファリングの構成」を参照してください。

Webサービスの信頼性のあるメッセージングのWS-Policyファイルの作成

WS-Policyファイルは、WS-Policy仕様に準拠するポリシー・アサーションを含むXMLファイルです。この場合、WS-PolicyファイルにはWebサービスの信頼性のあるメッセージングのポリシー・アサーションが含まれています。

WebLogic Serverには、標準的な信頼性のあるメッセージング・アサーションを含むWS-Policyファイルがあらかじめパッケージ化されています。独自のWS-Policyファイルを作成しない場合は、これらのファイルを使用できます。

次の表に、あらかじめパッケージ化されているWS-Policyファイルを示します。この表は、WS-Policyファイルをメソッド・レベルでアタッチできるかどうかも指定します。この列の値が「No」の場合、WS-Policyファイルをクラス・レベルでのみアタッチできます。詳細は、付録A「Webサービスの信頼性のあるメッセージングと接続作成のためのあらかじめパッケージ化されたWS-Policyファイル」を参照してください。

注意:

このリリースでは、DefaultReliability.xmlファイルとLongRunningReliability.xmlファイルは非推奨となっています。DefaultReliability1.2.xml、Reliability1.2_SequenceTransportSecurity、またはReliability1.0_1.2.xmlファイルを使用することをお薦めし、http://docs.oasis-open.org/ws-rx/wsrm/200702/wsrm-1.2-spec-os.pdfであるWS-ReliableMessaging仕様の1.2バージョンに準拠する必要があります。

表6-7 信頼性のあるメッセージングをサポートする、あらかじめパッケージ化されているWS-Policyファイル

あらかじめパッケージ化されているWS-Policyファイル

説明

メソッド・レベルのアタッチ

DefaultReliability1.2.xml

配信保証に関するポリシー・アサーションを指定します。Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrmp/200702のWS Reliable Messaging Policy Assertion 1.2が基になっています。「DefaultReliability1.1.xml (WS-Policyファイル)」を参照してください。

はい

DefaultReliability1.1.xml

サービス品質に関するポリシー・アサーションを指定します。Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrmp/200702/wsrmp-1.1-spec-os-01.htmlのWS Reliable Messaging Policy Assertion 1.1が基になっています。「DefaultReliability1.1.xml (WS-Policyファイル)」を参照してください。

はい

Reliability1.2_ExactlyOnce_WithMC1.1.xml

サービス品質に関するポリシー・アサーションを指定します。Webサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。「Reliability1.2_ExactlyOnce_WithMC1.1.xml(WS-Policyファイル)」を参照してください。

いいえ

Reliability1.2_SequenceSTRSecurity

信頼性のあるシーケンスでメッセージを保護するために、CreateSequenceメッセージで参照されるwsse:SecurityTokenReferenceをランタイムが使用するように指定します。Webサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrmp/200702のWS Reliable Messaging Policy Assertion 1.2が基になっています。「Reliability1.2_SequenceTransportSecurity.xml(WS-Policyファイル)」を参照してください。

いいえ

Reliability1.1_SequenceSTRSecurity

Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrmp/200702/wsrmp-1.1-spec-os-01.htmlのWS Reliable Messaging Policy Assertion 1.1が基になっています。「Reliability1.1_SequenceTransportSecurity.xml(WS-Policyファイル)」を参照してください。

はい

Reliability1.2_SequenceTransportSecurity

トランスポート・レベルのセキュリティとサービス品質に関連するポリシー・アサーションを指定します。Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrmp/200702のWS Reliable Messaging Policy Assertion 1.2が基になっています。「Reliability1.2_SequenceTransportSecurity.xml(WS-Policyファイル)」を参照してください。

はい

Reliability1.1_SequenceTransportSecurity

トランスポート・レベルのセキュリティとサービス品質に関連するポリシー・アサーションを指定します。Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrmp/200702/wsrmp-1.1-spec-os-01.htmlのWS Reliable Messaging Policy Assertion 1.1が基になっています。「Reliability1.1_SequenceTransportSecurity.xml(WS-Policyファイル)」を参照してください。

はい

Reliability1.0_1.2.xml

1.2と1.0のWS-Reliableメッセージング・ポリシー・アサーションを結合します。1.2バージョンのポリシー・アサーションはWebサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。このサンプルは、適切なポリシーの選択に基づいて実行時に適用されるポリシー・アサーションを決定します。「Reliability1.0_1.2.xml(WS-Policyファイル)」を参照してください。

いいえ

Reliability1.0_1.1.xml

1.1と1.0のWS Reliable Messagingポリシー・アサーションを結合します。「Reliability1.0_1.1.xml(WS-Policy.xmlファイル)」を参照してください。

はい

DefaultReliability.xml

非推奨。Webサービスの信頼性のあるメッセージングのアサーションは、WS Reliable Messaging Policy Assertion Version 1.0(http://schemas.xmlsoap.org/ws/2005/02/rm/WS-RMPolicy.pdf)に基づいています。このリリースでは、信頼性のあるメッセージングのポリシー・アサーションの多くが、JWSアノテーションまたは構成を通じて管理されます。

信頼性のあるメッセージングのポリシー・アサーションに一般的な値(非アクティブ・タイムアウト10分、確認応答の間隔200ミリ秒、基本的な再送信間隔3秒など)を指定します。「DefaultReliability.xml WS-Policyファイル(WS-Policy)[非推奨]」を参照してください。

はい

LongRunningReliability.xml

非推奨。長期実行プロセスに関して、Webサービスの信頼性のあるメッセージングのアサーションは、WS Reliable Messaging Policy Assertion Version 1.0に基づいています。このリリースでは、信頼性のあるメッセージングのポリシー・アサーションの多くが、JWSアノテーションまたは構成を通じて管理されます。

1つ前に示した、信頼性のあるメッセージングのデフォルトWS-Policyファイルとほぼ同じですが、アクティビティのタイムアウト間隔に、より大きな値(24時間)を指定する点が異なります。「LongRunningReliability.xml WS-Policyファイル(WS-Policy)[非推奨]」を参照してください。

はい

WebLogic Serverに含まれる、あらかじめパッケージ化されている信頼性のあるメッセージングWS-Policyファイルの1つを使用できます。これらのファイルは、ほとんどの場合に適合しています。あらかじめパッケージ化されているファイルは変更できません。値がニーズを満たさない場合は、カスタムのWS-Policyファイルを作成する必要があります。以下の節で、カスタムWS-Policyファイルの作成方法を説明します。

- WS-ReliableMessagingポリシー・アサーション・バージョン1.2と1.1を使用したカスタムWS-Policyファイルの作成

- WS-ReliableMessagingポリシー・アサーション・バージョン1.0を使用したカスタムWS-Policyファイルの作成(非推奨)

- 複数のポリシー選択肢の使用

WS-ReliableMessagingポリシー・アサーション・バージョン1.2と1.1を使用したカスタムWS-Policyファイルの作成

この項では、次の仕様に基づいたWebサービスの信頼性のあるメッセージングのアサーションを含むカスタムWS-Policyファイルを作成する方法について説明します。

- http://docs.oasis-open.org/ws-rx/wsrmp/200702/wsrmp-1.2-spec-os.htmlのWS Reliable Messaging Policy Assertion Version 1.2

- http://docs.oasis-open.org/ws-rx/wsrmp/200702/wsrmp-1.1-spec-os-01.htmlのWS Reliable Messaging Policy Assertion Version 1.1

WS-Policyファイルのルート要素は<Policy>であり、次のネームスペース宣言が含まれている必要があります。

<wsp:Policy
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">

Webサービスの信頼性のあるメッセージングのポリシー・アサーションはすべて、<wsrmp:RMAssertion>要素の内部でラップします。この要素には、Webサービスの信頼性のあるメッセージングのポリシー・アサーションを使用するため、次のネームスペース宣言が含まれている必要があります。

<wsrmp:RMAssertion
xmlns:wsrmp="http://docs.oasis-open.org/ws-rx/wsrmp/200702">

次の表に、WS-Policyファイルで指定可能なWebサービスの信頼性のあるメッセージングのアサーションを示します。アサーションの指定順序は重要です。次のアサーションを指定できますが、WS-Policyファイルでは次の一覧の順序どおりに指定する必要があります。

表6-8 Webサービスの信頼性のあるメッセージング・アサーション(バージョン1.2および1.1)

アサーション

説明

<wsrmp:SequenceSTR>

信頼性のあるシーケンスでメッセージを保護するため、ランタイムではCreateSequenceメッセージで参照されるwsse:SecurityTokenReferenceが使用されます。指定できるセキュリティ・アサーションは1つのみとなります。つまり、wsrmp:SequenceSTRまたはwsrmp:SequenceTransportSecurityのいずれか1つは指定できますが、両方は指定できません。

<wsrmp:SequenceTransportSecurity>

信頼性のあるシーケンスでメッセージを保護するため、ランタイムではCreateSequenceメッセージの送信に使用されるSSLトランスポート・セッションが使用されます。このアサーションは、特定の転送レベル・セキュリティ・メカニズム(sp:HttpsTokenなど)の使用を要求するsp:TransportBindingアサーションとともに使用する必要があります。指定できるセキュリティ・アサーションは1つのみとなります。つまり、wsrmp:SequenceSTRまたはwsrmp:SequenceTransportSecurityのいずれか1つは指定できますが、両方は指定できません。

<wsrm:DeliveryAssurance>

Webサービスの配信保証レベル(配信品質)。有効な値は、AtMostOnce、AtLeastOnce、ExactlyOnceおよびInOrder。次の表に定義されている配信保証レベルのいずれか1つを設定できます。設定しない場合、配信保証レベルはデフォルトのExactlyOnceが使用されます。配信保証の詳細は、表6-1を参照してください。

次の例では、簡単なWebサービスの信頼性のあるメッセージングのWS-Policyファイルを示します。

<?xml version="1.0"?>

<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsrmp:RMAssertion
xmlns:wsrmp="http://docs.oasis-open.org/ws-rx/wsrmp/200702">
<wsrmp:SequenceTransportSecurity/>
<wsrmp:DeliveryAssurance>
<wsp:Policy>
<wsrmp:ExactlyOnce/>
</wsp:Policy>
</wsrmp:DeliveryAssurance>
</wsrmp:RMAssertion>
</wsp:Policy>

WS-Policyファイルにおける信頼性のあるメッセージングのポリシー・アサーションの詳細は、『Oracle WebLogic Server WebLogic Webサービス・リファレンス』のWebサービスの信頼性のあるメッセージングのポリシー・アサーションに関するリファレンスの項を参照してください。

WS-ReliableMessagingポリシー・アサーション・バージョン1.0を使用したカスタムWS-Policyファイルの作成(非推奨)

この項では、WS Reliable Messaging Policy Assertion Version 1.0(http://schemas.xmlsoap.org/ws/2005/02/rm/WS-RMPolicy.pdf)に基づいたWebサービスの信頼性のあるメッセージングのアサーションを含むカスタムWS-Policyファイルを作成する方法について説明します。

注意:

この項で説明されている信頼性のあるメッセージング・ポリシー・アサーションの多くは、JWSのアノテーションまたは構成を通じて管理されます。

WS-Policyファイルのルート要素は<Policy>です。Webサービスの信頼性のあるメッセージングのポリシー・アサーションを使用するには、これに次のネームスペース宣言が含まれていることが必要です。

<wsp:Policy
xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:beapolicy="http://www.bea.com/wsrm/policy">

Webサービスの信頼性のあるメッセージングのポリシー・アサーションはすべて、<wsrm:RMAssertion要素の内部でラップします。wsrm:ネームスペースを使用するアサーションは、WS-ReliableMessaging仕様(http://docs.oasis-open.org/ws-rx/wsrm/200702/wsrm-1.1-spec-os-01.pdf)で定義される標準的なアサーションです。beapolicy:ネームスペースを使用するアサーションは、WebLogic固有のものです。詳細は、『Oracle WebLogic Server WebLogic Webサービス・リファレンス』のWebサービスの信頼性のあるメッセージングのポリシー・アサーションに関するリファレンスの項を参照してください。

次の表に、WS-Policyファイルで指定可能なWebサービスの信頼性のあるメッセージングのアサーションを示します。Webサービスの信頼性のあるメッセージングのアサーションは、すべてオプションなので、デフォルト値が不適切なものだけを設定します。アサーションの指定順序は重要です。次のアサーションを指定できますが、WS-Policyファイルでは次の一覧の順序どおりに指定する必要があります。

表6-9 Webサービスの信頼性のあるメッセージング・アサーション(バージョン1.0)

アサーション

説明

<wsrm:InactivityTimeout>

非アクティブ間隔を定義する、Milliseconds属性で指定されるミリ秒数。この時間が経過した時点で、宛先エンドポイントがソース・エンドポイントからのメッセージを受け取っていなければ、宛先エンドポイントは、処理が行われずシーケンスは終了したものと見なす場合があります。これは、ソース・エンドポイントについても同様のことが言えます。デフォルトでは、シーケンスがタイムアウトすることはありません。

<wsrm:BaseRetransmissionInterval>

ソース・エンドポイントがメッセージを送信してから、そのメッセージの確認応答を受け取っていない場合に再送信を行うまでの間隔(ミリ秒単位)。デフォルト値は、ソース・エンドポイントのWebLogic Serverインスタンス上のSAFエージェントによって設定されます。

<wsrm:ExponentialBackoff>

再送信の間隔が、指数関数的なバックオフ・アルゴリズムを使用して調整されることを指定します。この要素に属性はありません。

<wsrm:AcknowledgmentInterval>

宛先エンドポイントがスタンドアロンの確認応答を送信しなければならない最大間隔(ミリ秒単位)。デフォルト値は、宛先エンドポイントのWebLogic Serverインスタンス上のSAFエージェントによって設定されます。

<beapolicy:Expires>

信頼性のあるWebサービスの有効期限が切れ、これ以上の新しいシーケンス・メッセージを受け付けなくなるまでの時間の長さ。デフォルト値では、有効期限が切れることはありません。この要素には、Expiresという1つの属性があります。この属性のデータ型はXMLスキーマ期間型です。(http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#durationを参照。)たとえば、有効期限までを1日と設定する場合は、<beapolicy:Expires Expires="P1D" />とします。

<beapolicy:QOS>

表6-1で説明されている、配信保証レベル。この要素にはQOSという1つの属性があり、この属性はAtMostOnce、AtLeastOnce、ExactlyOnceの各値のうちの1つに設定します。また、メッセージを順序通りにすることを指定するためにInOrder文字列を含めることもできます。デフォルト値はExactlyOnce InOrderです。この要素は通常、設定されません。

次の例では、簡単なWebサービスの信頼性のあるメッセージングのWS-Policyファイルを示します。

<?xml version="1.0"?>

<wsp:Policy
xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm/policy"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:beapolicy="http://www.bea.com/wsrm/policy"
>
<wsrm:RMAssertion>
<wsrm:InactivityTimeout
Milliseconds="600000" />
<wsrm:BaseRetransmissionInterval
Milliseconds="500" />
<wsrm:ExponentialBackoff />
<wsrm:AcknowledgementInterval
Milliseconds="2000" />
</wsrm:RMAssertion>
</wsp:Policy>

WS-Policyファイルにおける信頼性のあるメッセージングのポリシー・アサーションの詳細は、『Oracle WebLogic Server WebLogic Webサービス・リファレンス』のWebサービスの信頼性のあるメッセージングのポリシー・アサーションに関するリファレンスの項を参照してください。

複数のポリシー選択肢の使用

カスタム・ポリシー・ファイルを作成することによって、単一のWebサービスに対して複数のポリシー選択肢(適切なポリシー選択肢)を構成できます。実行時には、適用されるポリシーがそれらの中から自動的に選択されます。その際は、サポートされていないポリシーやアサーションが競合しているポリシーが除外され、構成されているプリファレンスに基づいて、受信メッセージの検証とレスポンス・メッセージの構築に適したポリシーが選択されます。

次の例では、1.2と1.0 WSの信頼性のあるメッセージングの両方をサポートするセキュリティ・ポリシーの例を示します。各ポリシー選択肢は、<wsp:All>要素で囲まれています。

注意:

1.0のWebサービスの信頼性のあるメッセージング・アサーションには、接頭辞としてwsrmp10が付加されます。

<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsp:ExactlyOne>
<wsp:All>
<wsrmp10:RMAssertion
xmlns:wsrmp10="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
<wsrmp10:InactivityTimeout Milliseconds="1200000"/>
<wsrmp10:BaseRetransmissionInterval Milliseconds="60000"/>
<wsrmp10:ExponentialBackoff/>
<wsrmp10:AcknowledgementInterval Milliseconds="800"/>
</wsrmp10:RMAssertion>
</wsp:All>
<wsp:All>
<wsrmp:RMAssertion
xmlns:wsrmp="http://docs.oasis-open.org/ws-rx/wsrmp/200702">
<wsrmp:SequenceSTR/>
<wsrmp:DeliveryAssurance>
<wsp:Policy>
<wsrmp:AtMostOnce/>
</wsp:Policy>
</wsrmp:DeliveryAssurance>
</wsrmp:RMAssertion>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>

複数のポリシー選択肢の詳細は、『Oracle WebLogic Server WebLogic Webサービスの保護』の適切なポリシーの選択に関する項を参照してください。

信頼性のあるJWSファイルに関するプログラミングのガイドライン

注意:

信頼性のあるWebサービスの開発に関するベスト・プラクティスについては、第5章「信頼性のあるWebサービスとクライアントを開発する手順」を参照してください。

信頼性のあるメッセージングのアサーションが含まれるWS-PolicyファイルをWebサービスに追加するよう指定するには、JWSファイルで@Policyアノテーションを使用します。WebLogic Serverでは、あらかじめパッケージ化されているWS-Policyファイルのセットが提供されます。付録A「Webサービスの信頼性のあるメッセージングと接続作成のためのあらかじめパッケージ化されたWS-Policyファイル」を参照してください。

Webサービスの信頼性のあるメッセージングで@Policyアノテーションを使用する場合は、次のガイドラインに従います。

- uri属性を使用して、ポリシー・ファイルのビルド時の場所を以下のように指定します。

- 独自のWS-Policyファイルを作成した場合は、JWSファイルを基準として相対的に場所を指定します。例:

@Policy(uri="ReliableHelloWorldPolicy.xml",
direction=Policy.Direction.both,
attachToWsdl=true)

この例では、ReliableHelloWorldPolicy.xmlファイルがJWSファイルと同じディレクトリに置かれています。

- あらかじめパッケージ化されているWS-Policyファイルの1つか、共有Java EEライブラリにパッケージ化されているWS-Policyファイルを指定するには、そのポリシー・ファイルの名前とパスとともにpolicy:接頭辞を使用します。この構文ではビルド時のjwsc Antタスクに、ファイル・システムの実際のファイルを探させず、Webサービスが、サービスのデプロイ時にWebLogic ServerからWS-Policyファイルを取得することを通知しています。

注意:

共有Java EEライブラリは、様々なエンタープライズ・アプリケーション内にパッケージ化されている複数のWebサービスとWS-Policyファイルを共有する場合に有用です。WS-Policyファイルが共有Java EEライブラリのMETA-INF/policiesまたはWEB-INF/policiesディレクトリに置かれているかぎり、ポリシー・ファイルはWebサービスの同じアーカイブにパッケージ化されている場合と同様に指定できます。ライブラリの作成、およびWebサービスがポリシー・ファイルを見つけることができるようにするための環境設定については、『Oracle WebLogic Serverアプリケーションの開発』の共有Java EEライブラリおよびオプション・パッケージの作成に関する項を参照してください。

- ポリシー・ファイルをWeb上で公開するよう指定するには、次の例に示すとおり、URLと共にhttp:接頭辞を使用します。

@Policy(uri="http://someSite.com/policies/mypolicy.xml"
direction=Policy.Direction.both,
attachToWsdl=true)

- デフォルトでは、WS-Policyファイルはリクエスト(着信)とレスポンス(発信)の両方のSOAPメッセージに適用されます。このデフォルトの動作は、direction属性をPolicy.Direction.inboundまたはPolicy.Direction.outboundに設定すると変更できます。

- uriで指定されるポリシー・ファイル内でwsp:optional属性を使用し、Webサービスで操作が確実に呼び出され、そのレスポンスが確実に配信されるよう要求するかどうかを指定できます。
次の点に注意してください:

- クライアントが同期トランスポートを使用してWebサービスを呼び出し、操作のインバウンド方向で信頼性が必要な場合は(optional属性がfalse)、クライアントは信頼性のあるレスポンスを送信する時使用できるようにofferシーケンスを提供する必要があります(http://docs.oasis-open.org/ws-rx/wsrm/200702/wsrm-1.1-spec-os-01.pdfにあるWS-ReliableMessaging仕様で説明されている<wsrm: Offer...>)。

- クライアントが非同期トランスポートを使用する場合は、クライアントはofferシーケンスを送信する必要はありません。リクエストが信頼性を持って行われて、アウトバウンド方向にRMポリシーがある場合(オプションかどうか)信頼性のあるメッセージングのランタイムは、レスポンスを送信するために新しいRMシーケンスのハンドシェイクを強制します。この新しいシーケンスはリクエスト・シーケンスと関連付けられ、それ以降のすべてのレスポンスは新しいレスポンス・シーケンスで送信されます。レスポンス・シーケンスは、リクエストのReplyToアドレスで示されているエンドポイントとネゴシエーションされます。

- @PolicyアノテーションのattachToWsdl属性を設定して、ポリシー・ファイルをWebサービスのパブリック規約が記述されたWSDLファイルに付加するかどうかを指定できます。通常は、クライアント・アプリケーションでWebサービスの信頼性のあるメッセージング機能が認識されるよう、パブリックなものとしてポリシーを公開します。そのため、この属性のデフォルト値はtrueです。

@Policyアノテーションの詳細は、『Oracle WebLogic Server WebLogic Webサービス・リファレンス』のweblogic.jws.Policyに関する項を参照してください。

例6-1では、信頼性のあるWebサービスを実装する簡単なJWSファイルを示します。

例6-1 信頼性のあるWebサービスの例

import javax.jws.WebService;

import weblogic.jws.Policies;
import weblogic.jws.Policy;

/**
* Example Web service for reliable client best practice examples
*/
@WebService
// Enable RM on this service.
@Policies( { @Policy(uri = "policy:DefaultReliability1.2.xml") })
public class BackendReliableService {

public String doSomething(String what) {

System.out.println("BackendReliableService doing: " + what);

return "Did (Reliably) '" + what + "' at: " + System.currentTimeMillis();
}
}

この例では、事前に定義されたDefaultReliability1.2.xmlポリシー・ファイルがクラス・レベルでWebサービスにアタッチされています。つまり、ポリシー・ファイルはWebサービスのすべてのパブリック操作(doSomething())に適用されます。ポリシー・ファイルは、デフォルトでリクエストとレスポンスの両方に適用されます。あらかじめパッケージ化されている利用可能なポリシーおよびカスタム・ポリシーの作成の詳細につぃては、「Webサービスの信頼性のあるメッセージングのWS-Policyファイルの作成」を参照してください。

Webサービス・クライアントからの信頼性のあるWebサービスの呼出し

注意:

信頼性のあるWebサービス・クライアントの開発に関するベスト・プラクティスについては、「信頼性のあるWebサービス・クライアントを開発する手順」を参照してください。

次の表では、使用するトランスポート・タイプに基づいてWebサービス・クライアントから信頼性のあるWebサービスを呼び出す方法を示します。トランスポート・タイプの詳細は、表6-2を参照してください。

表6-10 トランスポート・タイプに基づく信頼性のあるWebサービスの呼出し

トランスポート・タイプ

説明

非同期トランスポート

非同期トランスポートを使用するには、次の手順を実行します。

1. Webサービス・クライアントを実装します(表4-3「非同期でWebサービスを呼び出すための手順」を参照)。
表4-3の手順3で、クライアントがファイアウォールの内側にあるかどうかに応じて、次のいずれかのトランスポート・メカニズムを実装します。

- 非同期クライアント・トランスポート機能(「スケーラブルな非同期JAX-WSクライアントの開発(非同期クライアント・トランスポート)」を参照)。

- クライアントがファイアウォールの内側にある場合は接続作成(「ファイアウォールの内側からの非同期Webサービス・クライアントの使用(接続作成)」を参照)。

2. 同期または非同期の呼出しセマンティクスを使用して、Webサービスを呼び出します。
注意: 非同期クライアント・トランスポートまたは接続作成が有効になっているときは、同期操作を呼び出すことができます(「同期操作用の非同期クライアント・トランスポートの構成」および「同期メソッドのトランスポートとしての接続作成の構成」を参照)。

同期トランスポート

同期トランスポートを使用するには、標準のJAX-WS参照実装を使用して、信頼性のあるメッセージング・サービスのポート・インスタンスで非同期メソッドまたは同期メソッドを呼び出します(「JAX-WS参照実装の使用」を参照)。

注意: 同期トランスポートを使用してバッファ付きWebサービスを呼び出そうとした場合、結果は次のいずれかになります。

- シーケンスの最初のリクエストの場合、宛先のシーケンスはバッファなしに設定されます(Webサービスの構成がバッファなしとして設定されていた場合と同様)。

- シーケンスの最初のリクエストではない場合は(つまり、クライアントが前に非同期トランスポートを使用してリクエストを送信していた場合)、リクエストは破棄されてエラーが返されます。

クライアント側での追加の制御として、次のタスクを実行できます。

- クライアント側で信頼性のあるメッセージングを構成します(「信頼性のあるメッセージングの構成」を参照)。

- 信頼性のある配信が失敗した場合に通知を受け取る信頼性エラー・リスナーを実装します(「信頼性エラー・リスナーの実装」を参照)。ベスト・プラクティスとして信頼性エラー・リスナーを常に実装することをお薦めします。

- 構成オプションの設定、信頼性のあるシーケンスIDの取得、信頼性のあるシーケンスの終了など、信頼性のあるメッセージング・シーケンスに対する一般的なライフサイクル・タスクを実行します(「信頼性のあるメッセージ・シーケンスのライフサイクルの管理」を参照)。

信頼性のあるメッセージングの構成

注意:

信頼性のあるWebサービスの構成に関するベスト・プラクティスについては、第5章「信頼性のあるWebサービスとクライアントを開発する手順」を参照してください。

WebLogic Server、Webサービス・エンドポイント、Webサービス・クライアントのレベルで、信頼性のあるWebサービスとクライアントのプロパティを構成できます。

WebLogic Serverレベルで定義したプロパティは、そのサーバーのすべての信頼性のあるWebサービスとクライアントに適用されます。WebLogic Serverレベルでの信頼性のあるメッセージングの構成の詳細は、「WebLogic Serverでの信頼性のあるメッセージングの構成」を参照してください。

必要がある場合は、次のようにして、サーバー・レベルで定義されている信頼性のあるメッセージングの構成オプションをオーバーライドできます。

- Webサービス・エンドポイント・レベルで、アプリケーション・デプロイメント・プランを更新します。デプロイメント・プランは、新しい値をアプリケーションの記述子内の特定の場所に関連付け、weblogic-webservices.xml記述子に保存されます。デプロイメント時に、デプロイメント・プランは変数割当ての値を、その変数のリンク先アプリケーション記述子内の場所に適用することによって、そのアプリケーション内の記述子に結合されます。詳細は、「Webサービス・エンドポイントでの信頼性のあるメッセージングの構成」を参照してください。

- Webサービスのクライアント・レベル。詳細は、「Webサービス・クライアントでの信頼性のあるメッセージングの構成」を参照してください。

次の項では、WebLogic Server、Webサービス・エンドポイント、Webサービス・クライアントの各レベルで信頼性のあるメッセージングを構成する方法を説明します。

- WebLogic Serverでの信頼性のあるメッセージングの構成

- Webサービス・エンドポイントでの信頼性のあるメッセージングの構成

- Webサービス・クライアントでの信頼性のあるメッセージングの構成

- 基本の再送信間隔の構成

- 再送信間隔の指数関数的バックオフの構成

- 順序の有効期限の構成

- 非アクティブ・タイムアウトの構成

- Webサービスのバッファなし宛先の構成

- 確認応答の間隔の構成

- 信頼性エラー・リスナーの実装

WebLogic Serverでの信頼性のあるメッセージングの構成

WebLogic Serverでの信頼性のあるメッセージングは、管理コンソールまたはWLSTを使用して構成できます。以降の項を参照してください。

- 管理コンソールを使用する

- WLSTの使用

管理コンソールを使用する

管理コンソールを使用してWebLogic Serverに対して信頼性のあるメッセージングを構成するには、次の手順に従います。

1. 『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebLogic Server管理コンソールの使用に関する項の説明に従って、管理コンソールを起動します。

2. 左側のナビゲーション・ペインで、「環境」、「サーバー」の順に選択します。

3. 「構成」タブを選択し、「サーバー」表で、信頼性のあるメッセージングの構成の対象となるサーバーの名前をクリックします。

4. 「構成」タブ、「Webサービス」タブ、「信頼できるメッセージ」タブの順にクリックします。

5. 次の項の説明に従って、信頼性のあるメッセージングのプロパティを編集します。

- WebLogic ServerまたはWebサービス・エンドポイントでの基本の再送信間隔の構成

- WebLogic ServerまたはWebサービス・エンドポイントでの再送信間隔の指数関数的バックオフの構成

- WebLogic ServerまたはWebサービス・エンドポイントでの順序の有効期限の構成

- WebLogic ServerまたはWebサービス・エンドポイントでの非アクティブ・タイムアウトの構成

- Webサービスのバッファなし宛先の構成

- 確認応答の間隔の構成

6. 「保存」をクリックします。

詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのWebサービスの信頼性のあるメッセージングに関する項を参照してください。

WLSTの使用

または、WLSTを使用して、信頼性のあるメッセージングを構成することもできます。WLSTを使用したドメインの拡張の詳細は、『Oracle WebLogic Scripting Tool』の既存ドメインの構成に関する項を参照してください。

Webサービス・エンドポイントでの信頼性のあるメッセージングの構成

既定では、Webサービス・エンドポイントは、サーバーに対して定義されている信頼性のあるメッセージングの構成を使用します。次のようにすると、Webサービス・エンドポイントで使用される信頼性のあるメッセージングの構成を、管理コンソールを使用してオーバーライドできます。

注意:

または、WLSTを使用して、信頼性のあるメッセージングを構成することもできます。WLSTを使用したドメインの拡張の詳細は、『Oracle WebLogic Scripting Tool』の既存ドメインの構成に関する項を参照してください。

1. 『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』の管理コンソールの起動に関する項の説明に従って、管理コンソールを起動します。

2. 左側のナビゲーション・ペインで、「デプロイメント」を選択します。

3. 「デプロイメント」表でWebサービスの名前をクリックします。

4. 「構成」タブ、「ポート・コンポーネント」タブの順に選択します。

5. 「ポート」表でWebサービスのエンドポイントの名前をクリックします。

6. 「信頼できるメッセージ」タブを選択します。

7. 「信頼性のあるメッセージ構成のカスタマイズ」をクリックし、必要に応じて、指示に従ってデプロイメント・プランを保存します。

8. 次の項の説明に従って、信頼性のあるメッセージングのプロパティを編集します。

- WebLogic ServerまたはWebサービス・エンドポイントでの基本の再送信間隔の構成

- WebLogic ServerまたはWebサービス・エンドポイントでの再送信間隔の指数関数的バックオフの構成

- WebLogic ServerまたはWebサービス・エンドポイントでの順序の有効期限の構成

- WebLogic ServerまたはWebサービス・エンドポイントでの非アクティブ・タイムアウトの構成

- Webサービスのバッファなし宛先の構成

- 確認応答の間隔の構成

9. 「保存」をクリックします。

詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのWebサービスの信頼性のあるメッセージングの構成に関する項を参照してください。

Webサービス・クライアントでの信頼性のあるメッセージングの構成

Webサービス・クライアントでの信頼性のあるメッセージングの構成の一般情報は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebサービス・クライアントの構成に関する項を参照してください。

Webサービスの信頼性のあるメッセージングのクライアントを作成するときのweblogic.wsee.reliability2.api.WsrmClientInitFeatureの使用の詳細は、次の項を参照してください。

- Webサービス・クライアントでの基本の再送信間隔の構成

- Webサービス・クライアントでの再送信間隔の指数関数的バックオフの構成

- Webサービス・クライアントでの順序の有効期限の構成

- Webサービス・クライアントでの非アクティブ・タイムアウトの構成

基本の再送信間隔の構成

ソース・エンドポイントが、指定された基本の再送信間隔内で所定のメッセージの確認応答を受信しなかった場合、ソース・エンドポイントはメッセージを再送信します。ソース・エンドポイントは、メッセージのシーケンスの存続期間内の任意の時点で、この再送信間隔を変更することがあります。

この間隔を再送信間隔の指数関数的バックオフ(「再送信間隔の指数関数的バックオフの構成」を参照)と組み合せて使用すると、再送信間隔を調整するアルゴリズムを指定できます。

指定する値はXMLスキーマの期間を表す字句形式(PnYnMnDTnHnMnS)に従った正の値でなければなりません。ここで、nYは年数、nMは月数、nDは日数を表し、Tは日付/時刻のセパレータ、nHは時間数、nMは分数、nSは秒数を表します。この値のデフォルトはP0DT5S (5秒)。

次の項では、基本の再送信間隔を構成する方法について説明します。

- WebLogic ServerまたはWebサービス・エンドポイントでの基本の再送信間隔の構成

- Webサービス・クライアントでの基本の再送信間隔の構成

WebLogic ServerまたはWebサービス・エンドポイントでの基本の再送信間隔の構成

管理コンソールを使用して、WebLogic ServerまたはWebサービス・エンドポイントのレベルで再送信間隔の指数関数的バックオフを構成するには、次の手順を実行します。

注意:

または、WLSTを使用して、信頼性のあるメッセージングを構成することもできます。WLSTを使用したドメインの拡張の詳細は、『Oracle WebLogic Scripting Tool』の既存ドメインの構成に関する項を参照してください。

1. 管理コンソールを起動し、次の項の説明に従って、サーバー・レベルまたはWebサービス・エンドポイント・レベルで、Webサービスの信頼性のあるメッセージングのページにアクセスします。

- WebLogic Serverでの信頼性のあるメッセージングの構成

- Webサービス・エンドポイントでの信頼性のあるメッセージングの構成

2. 必要に応じて、「基本の再送信間隔」の値を設定します。

Webサービス・クライアントでの基本の再送信間隔の構成

注意:

Webサービス・クライアントの構成の詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebサービス・クライアントの構成に関する項を参照してください。

表6-11では、メッセージをRM宛先に再送信する前に経過する必要のある時間を構成するためのweblogic.wsee.reliability2.api.WsrmClientInitFeatureメソッドについて説明します。

表6-11 基本の再送信間隔を構成するためのメソッド

メソッド

説明

String getBaseRetransmissionInterval()

基本の再送信間隔を取得します。

void setBaseRetransmissionInterval(String interval)

基本の再送信間隔を設定します。

次の例では、基本の再送信間隔を3時間に設定しています。

import java.xml.ws.WebService;
import java.xml.ws.WebServiceRef;
import wsrm_jaxws.example.client_service.*;
import wsrm_jaxws.example.client_service.EchoResponse;
import weblogic.wsee.reliability2.api.WsrmClientInitFeature;
...
@WebService
public class ClientServiceImpl {
...
@WebServiceRef(name="ReliableEchoService")
private ReliableEchoService service;
private ReliableEchoPortType port = null;
WsrmClientInitFeature initFeature = new WsrmClientInitFeature(true);
initFeature.setBaseRetransmissionInterval("P0DT3H");
port = service.getMyReliableServicePort(initFeature);
...

基本の再送信間隔の構成は、weblogic.xmlファイルでは次のように記述されます。

<service-reference-description>
...
<port-info>
<stub-property>
<name>weblogic.wsee.wsrm.BaseRetransmissionInterval</name>
<value>PT30S</value>
</stub-property>
...
</port-info>
</service-reference-description>

再送信間隔の指数関数的バックオフの構成

再送信間隔の指数関数的バックオフは、基本の再送信間隔(「基本の再送信間隔の構成」を参照)と組み合せて使用します。宛先エンドポイントが、基本の再送信間隔で指定した時間内にメッセージのシーケンスを確認応答しなかった場合、メッセージが引き続き確認されなければ、連続する再送信のタイミングに対して、送信元エンドポイントでは指数関数的バックオフ・アルゴリズムを使用します。

指数関数的なバックオフ・アルゴリズムは、連続再送信の間隔が、基本の再送信間隔を基に指数的に増えるように指定します。たとえば、基本の再送信間隔が2秒で、指数関数的なバックオフ要素が設定されている場合、連続再送信の間隔は、メッセージが確認されなければ、2、4、8、16、32秒というように増えていきます。

デフォルトではこのフラグは無効(false)であり、連続再送信の間隔は指数的に増えず、同じ値が維持されます。

次の項では、再送信間隔の指数関数的バックオフを構成する方法について説明します。

- WebLogic ServerまたはWebサービス・エンドポイントでの再送信間隔の指数関数的バックオフの構成

- Webサービス・クライアントでの再送信間隔の指数関数的バックオフの構成

WebLogic ServerまたはWebサービス・エンドポイントでの再送信間隔の指数関数的バックオフの構成

管理コンソールを使用して、WebLogic ServerまたはWebサービス・エンドポイントのレベルで再送信間隔の指数関数的バックオフを構成するには、次の手順を実行します。

注意:

または、WLSTを使用して、信頼性のあるメッセージングを構成することもできます。WLSTを使用したドメインの拡張の詳細は、『Oracle WebLogic Scripting Tool』の既存ドメインの構成に関する項を参照してください。

1. 管理コンソールを起動し、次の項の説明に従って、サーバー・レベルまたはWebサービス・エンドポイント・レベルで、Webサービスの信頼性のあるメッセージングのページにアクセスします。

- WebLogic Serverでの信頼性のあるメッセージングの構成

- Webサービス・エンドポイントでの信頼性のあるメッセージングの構成

2. 必要に応じて、「再送信間隔の指数関数的バックオフの有効化」フラグを設定します。

Webサービス・クライアントでの再送信間隔の指数関数的バックオフの構成

注意:

Webサービス・クライアントの構成の詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebサービス・クライアントの構成に関する項を参照してください。

表6-12では、メッセージの再送信間隔を再送信間隔の指数関数的バックオフ・アルゴリズムを使用して調整するかどうかを構成するためのweblogic.wsee.reliability2.api.WsrmClientInitFeatureメソッドについて説明します。

表6-12 再送信間隔の指数関数的バックオフを構成するためのメソッド

メソッド

説明

Boolean isRetransmissionExponentialBackoff()

再送信間隔の指数関数的バックオフが有効かどうかを示します。

void setBaseRetransmissionExponentialBackoff(boolean value)

再送信間隔の指数関数的バックオフが有効かどうかを指定します。有効な値はtrueまたはfalseです。

次の例では、再送信間隔の指数関数的バックオフを有効にしています。

import java.xml.ws.WebService;
import java.xml.ws.WebServiceRef;
import wsrm_jaxws.example.client_service.*;
import wsrm_jaxws.example.client_service.EchoResponse;
import weblogic.wsee.reliability2.api.WsrmClientInitFeature;
...
@WebService
public class ClientServiceImpl {
...
@WebServiceRef(name="ReliableEchoService")
private ReliableEchoService service;
private ReliableEchoPortType port = null;
WsrmClientInitFeature initFeature = new WsrmClientInitFeature(true);
initFeature.setBaseRetransmissionInterval("P0DT3H");
initFeature.setBaseRetransmissionExponentialBackoff(true);
port = service.getMyReliableServicePort(initFeature);
...

再送信間隔の指数関数的バックオフの構成は、weblogic.xmlファイルでは次のように記述されます。

<service-reference-description>
...
<port-info>
<stub-property>
<name>weblogic.wsee.wsrm.RetransmissionExponentialBackoff</name>
<value>true</value>
</stub-property>
...
</port-info>
</service-reference-description>

順序の有効期限の構成

順序の有効期限は、アクティビティにかかわらず、シーケンスが期限切れになるまでの時間を指定します。

指定する値はXMLスキーマの期間を表す字句形式(PnYnMnDTnHnMnS)に従った正の値でなければなりません。ここで、nYは年数、nMは月数、nDは日数を表し、Tは日付/時刻のセパレータ、nHは時間数、nMは分数、nSは秒数を表します。この値のデフォルトはP1D (1日)。

次の項では、順序の有効期限を構成する方法について説明します。

- WebLogic ServerまたはWebサービス・エンドポイントでの順序の有効期限の構成

- Webサービス・クライアントでの順序の有効期限の構成

WebLogic ServerまたはWebサービス・エンドポイントでの順序の有効期限の構成

管理コンソールを使用して、WebLogic ServerまたはWebサービス・エンドポイントのレベルで順序の有効期限を構成するには、次の手順を実行します。

注意:

または、WLSTを使用して、信頼性のあるメッセージングを構成することもできます。WLSTを使用したドメインの拡張の詳細は、『Oracle WebLogic Scripting Tool』の既存ドメインの構成に関する項を参照してください。

1. 管理コンソールを起動し、次の項の説明に従って、サーバー・レベルまたはWebサービス・エンドポイント・レベルで、Webサービスの信頼性のあるメッセージングのページにアクセスします。

- WebLogic Serverでの信頼性のあるメッセージングの構成

- Webサービス・エンドポイントでの信頼性のあるメッセージングの構成

2. 必要に応じて、「順序の有効期限」の値を設定します。

Webサービス・クライアントでの順序の有効期限の構成

注意:

Webサービス・クライアントの構成の詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebサービス・クライアントの構成に関する項を参照してください。

表6-13では、アクティビティにかかわらず順序が期限切れになるまでの時間に対するweblogic.wsee.reliability2.api.WsrmClientInitFeatureメソッドについて説明します。

表6-13 順序の有効期限を構成するためのメソッド

メソッド

説明

String getSequenceExpiration()

現在構成されている順序の有効期限を返します。

void setSequenceExpiration(String expiration)

アクティビティにかかわらず、シーケンスが期限切れになるまでの時間。

次の例では、順序の有効期限を36時間に設定しています。

import java.xml.ws.WebService;
import java.xml.ws.WebServiceRef;
import wsrm_jaxws.example.client_service.*;
import wsrm_jaxws.example.client_service.EchoResponse;
import weblogic.wsee.reliability2.api.WsrmClientInitFeature;
...
@WebService
public class ClientServiceImpl {
...
@WebServiceRef(name="ReliableEchoService")
private ReliableEchoService service;
private ReliableEchoPortType port = null;
WsrmClientInitFeature initFeature = new WsrmClientInitFeature(true);
initFeature.setSequenceExpiration("P0DT36H");
port = service.getMyReliableServicePort(initFeature);
...

順序の有効期限の構成は、weblogic.xmlファイルでは次のように記述されます。

<service-reference-description>
...
<port-info>
<stub-property>
<name>weblogic.wsee.wsrm.SequenceExpiration</name>
<value>PT10M</value>
</stub-property>
...
</port-info>
</service-reference-description>

非アクティブ・タイムアウトの構成

非アクティブ・タイムアウト間隔内に、エンドポイント(RM送信元とRM宛先)がアプリケーションのメッセージまたはプロトコル・メッセージを受け取らなければ、エンドポイントはRMシーケンスが非アクティブなため終了したものと見なします。

指定する値はXMLスキーマの期間を表す字句形式(PnYnMnDTnHnMnS)に従った正の値でなければなりません。ここで、nYは年数、nMは月数、nDは日数を表し、Tは日付/時刻のセパレータ、nHは時間数、nMは分数、nSは秒数を表します。この値のデフォルトはP0DT600S (600秒)。

次の項では、非アクティブ・タイムアウトを構成する方法について説明します。

- WebLogic ServerまたはWebサービス・エンドポイントでの非アクティブ・タイムアウトの構成

- Webサービス・クライアントでの非アクティブ・タイムアウトの構成

WebLogic ServerまたはWebサービス・エンドポイントでの非アクティブ・タイムアウトの構成

管理コンソールを使用して、WebLogic ServerまたはWebサービス・エンドポイントのレベルで非アクティブ・タイムアウトを構成するには、次の手順を実行します。

注意:

または、WLSTを使用して、信頼性のあるメッセージングを構成することもできます。WLSTを使用したドメインの拡張の詳細は、『Oracle WebLogic Scripting Tool』の既存ドメインの構成に関する項を参照してください。

1. 管理コンソールを起動し、次の項の説明に従って、サーバー・レベルまたはWebサービス・エンドポイント・レベルで、Webサービスの信頼性のあるメッセージングのページにアクセスします。

- WebLogic Serverでの信頼性のあるメッセージングの構成

- Webサービス・エンドポイントでの信頼性のあるメッセージングの構成

2. 必要に応じて、「非アクティブ・タイムアウト」の値を設定します。

Webサービス・クライアントでの非アクティブ・タイムアウトの構成

注意:

Webサービス・クライアントの構成の詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebサービス・クライアントの構成に関する項を参照してください。

表6-14では、非アクティブ・タイムアウトを構成するためのweblogic.wsee.reliability2.api.WsrmClientInitFeatureメソッドについて説明します。

表6-14 非アクティブ・タイムアウトを構成するためのメソッド

メソッド

説明

String getInactivityTimeout()

現在構成されている非アクティブ・タイムアウトを返します。

void setInactivityTimeout(String timeout)

非アクティブ・タイムアウトを設定します。

次の例では、非アクティブ・タイムアウトを1時間に設定しています。

import java.xml.ws.WebService;
import java.xml.ws.WebServiceRef;
import wsrm_jaxws.example.client_service.*;
import wsrm_jaxws.example.client_service.EchoResponse;
import weblogic.wsee.reliability2.api.WsrmClientInitFeature;
...
@WebService
public class ClientServiceImpl {
...
@WebServiceRef(name="ReliableEchoService")
private ReliableEchoService service;
private ReliableEchoPortType port = null;
WsrmClientInitFeature initFeature = new WsrmClientInitFeature(true);
initFeature.setInactivityTimeout("P0DT1H");
port = service.getMyReliableServicePort(initFeature);
...

非アクティブ・タイムアウトの構成は、weblogic.xmlファイルでは次のように記述されます。

<service-reference-description>
...
<port-info>
<stub-property>
<name>weblogic.wsee.wsrm.InactivityTimeout</name>
<value>PT5M</value>
</stub-property>
...
</port-info>
</service-reference-description>

Webサービスのバッファなし宛先の構成

特定の宛先サーバーでメッセージ・バッファリングを無効にするかどうかを指定し、メッセージを受信するときにバッファリングを使用するかどうかを制御できます。宛先サーバーでバッファなしを構成できるのは、WebLogic ServerまたはWebサービス・エンドポイントのレベルのみであり、Webサービス・クライアントのレベルでは構成できません(Webサービス・クライアントではバッファリングがデフォルトで有効になります)。

注意:

バッファなし宛先を構成した場合、@WebServiceRefを使用して構成の参照を定義しているすべてのWebサービス・クライアントは、レスポンスをバッファリングなしで受け取ります。

バッファなし宛先の構成は、weblogic.xmlファイルでは次のように記述されます。

<service-reference-description>
...
<port-info>
<stub-property>
<name>weblogic.wsee.wsrm.NonBufferedDestination</name>
<value>true</value>
</stub-property>
...
</port-info>
</service-reference-description>

@WebServiceRefの詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』の@WebServiceRefアノテーションを使用したWebサービス参照の定義に関する項を参照してください。

管理コンソールを使用して、WebLogic ServerまたはWebサービス・エンドポイントのレベルで、メッセージのバッファリングを無効にするように宛先サーバーを構成するには、次の手順を実行します。

注意:

または、WLSTを使用して、信頼性のあるメッセージングを構成することもできます。WLSTを使用したドメインの拡張の詳細は、『Oracle WebLogic Scripting Tool』の既存ドメインの構成に関する項を参照してください。

1. 管理コンソールを起動し、次の項の説明に従って、サーバー・レベルまたはWebサービス・エンドポイント・レベルで、Webサービスの信頼性のあるメッセージングのページにアクセスします。

- WebLogic Serverでの信頼性のあるメッセージングの構成

- Webサービス・エンドポイントでの信頼性のあるメッセージングの構成

2. 必要に応じて、「非バッファ宛先」の値を設定し、宛先サーバーを構成します。

注意:

送信元サーバーでは、メッセージのバッファリングは常に有効にする必要があります。つまり、「非バッファ送信元」の値は常に無効にしておく必要があります。

確認応答の間隔の構成

確認応答の間隔では、宛先エンドポイントがスタンドアロンの確認応答を送信する必要のある最大間隔を指定します。確認応答の間隔を構成できるのはWebLogic ServerまたはWebサービス・エンドポイントのレベルのみであり、Webサービス・クライアントのレベルでは構成できません。

注意:

@WebServiceRefを使用してWebサービスへの参照を定義しているWebサービス・クライアントは、確認応答の間隔の値を使用して、クライアントのレスポンス処理が確認応答の受信を待機する時間を制御します。つまり、クライアントは、レスポンス・メッセージを受信するときにRM宛先と同じように動作します。

バッファなし宛先の構成は、weblogic.xmlファイルでは次のように記述されます。

<service-reference-description>
...
<port-info>
<stub-property>
<name>weblogic.wsee.wsrm.AcknowledgementInterval</name>
<value>PT5S</value>
</stub-property>
...
</port-info>
</service-reference-description>

@WebServiceRefの詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』の@WebServiceRefアノテーションを使用したWebサービス参照の定義に関する項を参照してください。

宛先エンドポイントは、ソース・エンドポイントからメッセージを受信した直後に、返されたメッセージに対する確認応答を送信できます。また、スタンドアロンの確認応答として個別に確認応答を送信することもできます。返されたメッセージに対して確認応答を送信できない場合、宛先エンドポイントは、スタンドアロンの確認応答を送信するまで、確認応答の間隔に設定した時間範囲内で待機することがあります。未確認のメッセージがない場合、宛先エンドポイントは確認応答を送信しない可能性があります。

指定する値はXMLスキーマの期間を表す字句形式(PnYnMnDTnHnMnS)に従った正の値でなければなりません。ここで、nYは年数、nMは月数、nDは日数を表し、Tは日付/時刻のセパレータ、nHは時間数、nMは分数、nSは秒数を表します。この値のデフォルトはP0DT0.2S (0.2秒)です。

管理コンソールを使用して、WebLogic ServerまたはWebサービス・エンドポイントのレベルで確認応答の間隔を構成するには、次の手順を実行します。

注意:

または、WLSTを使用して、信頼性のあるメッセージングを構成することもできます。WLSTを使用したドメインの拡張の詳細は、『Oracle WebLogic Scripting Tool』の既存ドメインの構成に関する項を参照してください。

1. 管理コンソールを起動し、次の項の説明に従って、サーバー・レベルまたはWebサービス・エンドポイント・レベルで、Webサービスの信頼性のあるメッセージングのページにアクセスします。

- WebLogic Serverでの信頼性のあるメッセージングの構成

- Webサービス・エンドポイントでの信頼性のあるメッセージングの構成

2. 必要に応じて、「確認応答の間隔」の値を設定します。

信頼性エラー・リスナーの実装

リクエストを配信できない場合に信頼性のある配信の障害に関する通知を受け取るには、次のweblogic.wsee.reliability2.api.ReliabilityErrorListenerインタフェースを実装します。

public interface ReliablityErrorListener {

public void onReliabilityError(ReliabilityErrorContext context);
}

表6-15では、信頼性エラー・リスナーを構成するためのweblogic.wsee.reliability2.api.WsrmClientInitFeatureメソッドについて説明します。

表6-15 信頼性エラー・リスナーを構成するためのメソッド

メソッド

説明

ReliabilityErrorListener getReliabilityListener()

現在構成されている信頼性リスナーを取得します。

void setErrorListener(ReliabilityErrorListener errorListener)

信頼性エラー・リスナーを設定します。

次の例では、Webサービス・クライアントに信頼性エラー・リスナーを実装して使用する方法を示します。この例は、例5-1「信頼性のあるWebサービス・クライアントのベスト・プラクティスの例」からの抜粋です。

import weblogic.wsee.reliability2.api.ReliabilityErrorListener;
import weblogic.wsee.reliability2.api.WsrmClientInitFeature;
...
@WebService
public class ClientServiceImpl {
...
WsrmClientInitFeature rmFeature = new WsrmClientInitFeature();
features.add(rmFeature);

ReliabilityErrorListener listener = new ReliabilityErrorListener() {
public void onReliabilityError(ReliabilityErrorContext context) {

// At a *minimum* do this
System.out.println("RM sequence failure: " +
context.getFaultSummaryMessage());
_lastResponse = context.getFaultSummaryMessage();

// And optionally do this...

// The context parameter tells you whether a request or the entire
// sequence has failed. If a sequence fails, you'll get a notification
// for each undelivered request (if any) on the sequence.
if (context.isRequestSpecific()) {
// We have a single request failure (possibly as part of a larger
// sequence failure).
// We can get the original request back like this:
String operationName = context.getOperationName();
System.out.println("Failed to deliver request for operation '" +
operationName + "'. Fault summary: " +
context.getFaultSummaryMessage());
if ("DoSomething".equals(operationName)) {
try {
String request = context.getRequest(JAXBContext.newInstance(),
String.class);
System.out.println("Failed to deliver request for operation '" +
operationName + "' with content: " +
request);
Map<String, Serializable> requestProps =
context.getUserRequestContextProperties();
if (requestProps != null) {
// Fetch back any property you sent in
// JAXWSProperties.PERSISTENT_CONTEXT when you sent the
// request.
String myProperty = (String)requestProps.get(MY_PROPERTY);
System.out.println(myProperty + " failed!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
// The entire sequence has encountered an error.
System.out.println("Entire sequence failed: " +
context.getFaultSummaryMessage());

}
}
};

rmFeature.setReliabilityErrorListener(listener);

_features = features.toArray(new WebServiceFeature[features.size()]);

BackendReliableService anotherPort =
_service.getBackendReliableServicePort(_features);
...

信頼性のあるメッセージ・シーケンスのライフサイクルの管理

WebLogic Serverでは、Webサービスの信頼性のあるメッセージングで使用するためのクライアントAPI weblogic.wsee.reliability2.api.WsrmClientが提供されています。このAPIを使用して、構成オプションの設定、信頼性のあるシーケンスIDの取得、信頼性のあるシーケンスの終了などの一般的なライフサイクル・タスクを実行します。

次に示すように、WsrmClient APIのインスタンスには、weblogic.wsee.reliability2.api.WsrmClientFactoryメソッドを使用して信頼性のあるWebサービス・ポートからアクセスできます。

package wsrm_jaxws.example;
import java.xml.ws.WebService;
import java.xml.ws.WebServiceRef;
import wsrm_jaxws.example.client_service.*;
import wsrm_jaxws.example.client_service.EchoResponse;
import weblogic.wsee.reliability2.api.WsrmClientInitFeature;
...
@WebService
public class ClientServiceImpl {
...
@WebServiceRef(name="ReliableEchoService")
private ReliableEchoService service;
private ReliableEchoPortType port = null;
port = service.getReliableEchoPort();
WsrmClient wsrmClient = WsrmClientFactory.getWsrmClientFromPort(port);
...

次の項では、WsrmClientを使用して信頼性のあるメッセージ・シーケンスのライフサイクルを管理する方法を説明します。

- 信頼性のあるシーケンスの管理

- クライアントIDの管理

- 確認応答済みリクエストの管理

- メッセージに関する情報へのアクセス

- 信頼性のあるシーケンスでの最後のメッセージの識別

- 信頼性のあるシーケンスを閉じる

- 信頼性のあるシーケンスの終了

- 新しいメッセージ・シーケンスを開始するためのクライアントのリセット

Webサービス・信頼性のあるメッセージング・クライアントAPIの詳細は、Oracle WebLogic Server APIリファレンスのweblogic.wsee.reliability2.api.WsrmClientを参照してください。

信頼性のあるシーケンスの管理

信頼性のあるシーケンスを管理するには、次のタスクを実行します。

- 信頼性のあるシーケンスIDを取得および設定します(「信頼性のあるシーケンスIDの取得および設定」を参照)。

- 信頼性のあるシーケンスの状態にアクセスし、たとえばアクティブかどうかや、終了されているかどうかなどを判定します(「信頼性のあるシーケンスの状態へのアクセス」を参照)。

信頼性のあるシーケンスIDの取得および設定

シーケンスIDは、特定の信頼性のあるシーケンスを識別するために使用されます。シーケンスIDの取得および設定は、それぞれ、weblogic.wsee.reliability2.api.WsrmClient.getSequenceID()メソッドおよびweblogic.wsee.reliability2.api.WsrmClient.setSequenceID()メソッドを使用します。getSequenceID()メソッドを発行した時点でメッセージが送信されていない場合、返される値はnullです。

例:

import weblogic.wsee.reliability2.api.WsrmClientFactory;
import weblogic.wsee.reliability2.api.WsrmClient;
...
_service = new BackendReliableServiceService();
...
features.add(... some features ...);
_features = features.toArray(new WebServiceFeature[features.size()]);
...
BackendReliableService anotherPort =
_service.getBackendReliableServicePort(_features);
...
WsrmClient rmClient = WsrmClientFactory.getWsrmClientFromPort(anotherPort);
...
// Will be null
String sequenceId = rmClient.getSequenceId();
// Send first message
anotherPort.doSomething("Bake a cake");
// Will be non-null
sequenceId = rmClient.getSequenceId();

サーバー障害からのリカバリ時には、新規作成したWebサービス上で信頼性のあるシーケンスを設定したり、クライアントまたはサーバーの再起動後にインスタンスをディスパッチしたりできます。クライアント・インスタンスのシーケンスIDの設定は高度な機能です。高度なクライアントは、setSequenceIdを使用してクライアント・インスタンスを既知のRMシーケンスに接続できます。

信頼性のあるシーケンスの状態へのアクセス

シーケンスの状態にアクセスするには、weblogic.wsee.reliability2.api.WsrmClient.getSequenceState()を使用します。このメソッドは、weblogic.wsee.reliability2.api.SequenceState型の定数java.lang.Enumを返します。

次の表では、シーケンスの状態に対して返される可能性のある有効な値を示します。

表6-16 シーケンスの状態の値

シーケンスの状態

説明

CLOSED

信頼性のあるシーケンスは閉じられています。

注意: シーケンスを閉じるのは、最後の手段と考える必要があり、すべてのリクエストを受信することがないと予想される信頼性のあるメッセージング・シーケンスを閉じる準備をするだけです。詳細は、「信頼性のあるシーケンスを閉じる」を参照してください。

CLOSING

信頼性のあるシーケンスは閉じられている途中です。

注意: シーケンスを閉じるのは、最後の手段と考える必要があり、すべてのリクエストを受信することがないと予想される信頼性のあるメッセージング・シーケンスを閉じる準備をするだけです。詳細は、「信頼性のあるシーケンスを閉じる」を参照してください。

CREATED

信頼性のあるシーケンスは作成されており、初期ハンドシェイクが完了しています。

CREATING

信頼性のあるシーケンスは作成されている途中であり、初期ハンドシェイクは進行中です。

LAST_MESSAGE

非推奨。WS-ReliableMessaging 1.0のみ。シーケンスの最後のメッセージを受信しました。

LAST_MESSAGE_PENDING

非推奨。WS-ReliableMessaging 1.0のみ。シーケンスの最後のメッセージは保留中です。

NEW

信頼性のあるシーケンスは初期状態です。初期ハンドシェイクは開始していません。

TERMINATED

信頼性のあるシーケンスは終了されました。

通常の処理では、最終メッセージまでのすべてのメッセージが確認応答された後は、信頼性のあるメッセージ・シーケンスは終了されます。お薦めはできませんが、信頼性のあるシーケンスを強制的に終了できます(「信頼性のあるシーケンスの終了」を参照)。

TERMINATING

信頼性のあるシーケンスは終了されている途中です。

通常の処理では、最終メッセージまでのすべてのメッセージが確認応答された後は、信頼性のあるメッセージ・シーケンスは終了されます。お薦めはできませんが、信頼性のあるシーケンスを強制的に終了できます(「信頼性のあるシーケンスの終了」を参照)。

例:

import weblogic.wsee.reliability2.api.WsrmClientFactory;
import weblogic.wsee.reliability2.api.WsrmClient;
import weblogic.wsee.reliability2.api.SequenceState;
...
_service = new BackendReliableServiceService();
...
features.add(... some features ...);
_features = features.toArray(new WebServiceFeature[features.size()]);
...
BackendReliableService anotherPort =
_service.getBackendReliableServicePort(_features);
...
WsrmClient rmClient = WsrmClientFactory.getWsrmClientFromPort(anotherPort);
...
SequenceState rmState = rmClient.getSequenceState();
if (rmState == SequenceState.TERMINATED) {
... Do some work or log a message ...
}
...

クライアントIDの管理

クライアントIDは、Webサービス・クライアントを示します。各クライアントは固有のIDを持っています。クライアントIDを使用して、クライアントまたはサーバーが再起動した後で信頼性のあるシーケンスに対して存在している可能性のある保存されたリクエストにアクセスできます。

クライアントIDは、WebLogic Serverによって自動的に構成されます。ポートを作成するときにweblogic.wsee.jaxws.persistence.ClientIdentityFeatureを使用して、クライアントIDをカスタム値に設定できます。詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のクライアントIDの管理に関する項を参照してください。

信頼性のあるメッセージングはクライアントIDを使用して、VMが再起動する前に送信されて、VMが終了する前に送信されなかったリクエストを発見します。以前のクライアントIDを使用して最初のクライアント・インスタンスを確立するとき、信頼性のあるメッセージングはそのポートと関連付けられているリソースを使用して、復元されたクライアントIDの代わりにリクエストの送信を開始します。

クライアントIDは、weblogic.wsee.reliability2.api.WsrmClient.getID()メソッドを使用して取得できます。

例:

import weblogic.wsee.reliability2.api.WsrmClientFactory;
import weblogic.wsee.reliability2.api.WsrmClient;
...
_service = new BackendReliableServiceService();
...
features.add(... some features ...);
_features = features.toArray(new WebServiceFeature[features.size()]);
...
BackendReliableService anotherPort =
_service.getBackendReliableServicePort(_features);
...
WsrmClient rmClient = WsrmClientFactory.getWsrmClientFromPort(anotherPort);
...
String clientId = rmClient.getId();
...

確認応答済みリクエストの管理

信頼性のあるメッセージ・シーケンスのライフサイクルの間に確認応答されたリクエストを表示するには、weblogic.wsee.reliability2.api.WsrmClient.ackRanges()メソッドを使用します。ackRanges()メソッドは、一連のweblogic.wsee.reliability.MessageRangeオブジェクトを返します。

確認応答が済んでいるリクエストの範囲を確認した後、クライアントは次を選択できます。

- weblogic.wsee.reliability2.api.WsrmClient.requestAcknowledgement()メソッドを使用して、RM宛先に確認応答リクエストを送信します。

- シーケンスを閉じ(「信頼性のあるシーケンスを閉じる」を参照)、特定の時間の後で確認応答されていないメッセージのアカウントに対してエラー処理を実行します。

注意: クライアントはgetAckRanges()を繰り返し呼び出して、信頼性のあるメッセージ・シーケンスを追跡できます。ただし、各呼出しにはある程度の追加オーバーヘッドが伴うことを考慮する必要があります。

メッセージに関する情報へのアクセス

weblogic.wsee.reliability2.api.WsrmClient.getMessageInfo()メソッドを使用すると、メッセージ番号に基づいて、クライアントから送信された信頼性のあるメッセージについての情報を取得できます。このメソッドは、クライアント・インスタンスから送信されたリクエスト・メッセージのシーケンシャル・メッセージ番号を表す長い値を受け取り、weblogic.wsee.reliability2.sequence.SourceMessageInfo型のメッセージに関する情報を返します。WsrmClient.getMostRecentMessageNumber()メソッドを使用すると、getMessageInfo()に渡すメッセージ番号の最大の値を特定できます。

返されるSourceMessageInfoオブジェクトは変更不可として扱う必要があり、getメソッドのみを使用する必要があります。

次の表では、送信元メッセージに関する特定の詳細にアクセスするために使用できるSourceMessageInfoメソッドの一覧を示します。

表6-17 SourceMessageInfo()のメソッド

メソッド

説明

getMessageID()

メッセージIDをString値として取得します。

getMessageNum()

メッセージの番号をlong値として取得します。

getResponseMessageInfo()

現在のSourceMessageInfo()オブジェクトによって表されるリクエストと関連付けられているレスポンスを表すweblogic.wsee.reliability2.sequence.DestinationMessageInfoオブジェクトを返します。このリクエストに対してレスポンスを受信していない場合、またはレスポンスが期待されない場合(たとえば、リクエストが一方向であった)は、NULLを返します。

isAck()

メッセージが確認応答されているかどうかを示します。

次の表では、宛先メッセージに関する特定の詳細にアクセスするために使用できるDestinationMessageInfoメソッドの一覧を示します。

表6-18 DestinationMessageInfo()のメソッド

メソッド

説明

getMessageID()

メッセージIDをString値として取得します。

getMessageNum()

メッセージの番号をlong値として取得します。

getMessageInfo()メソッドをweblogic.wsee.reliability2.api.WsrmClient.getMostRecentMessageNumber()と組み合わせて使用すると、最後に送信された信頼性のあるメッセージについての情報を取得できます。このメソッドは、1から始まり単調に増加するlong値を返します。次の状況では、このメソッドは-1を返します。

- 信頼性のあるシーケンスIDが設定されていない場合(getSequenceID()はnullを返します)。

- 最初の信頼性のあるメッセージがまだ送信されていません。

- 信頼性のあるシーケンスが終了されました。

信頼性のあるシーケンスでの最後のメッセージの識別

WebLogic Serverは信頼性のあるシーケンスと関連付けられたリソースを保持するので、適切なタイミングでこれらのリソースを解放することをお薦めします。通常の状況では、すべてのメッセージが送信され、RM宛先によって確認応答されるまで、信頼性のあるシーケンスを保持する必要があります。シーケンスの適切な終了を容易にするため、信頼性のあるメッセージ・シーケンスの最後のメッセージを識別することをお薦めします。これにより、RM宛先へのメッセージの送信が完了したことがわかり、WebLogic Serverは信頼性のあるシーケンスを自動的に終了する前に最後の確認応答の検索を開始できます。最後のメッセージを示すには、weblogic.wsee.reliability2.api.WsrmClient.setFinalMessage()メソッドを使用します。

最後のメッセージを識別すると、最後のメッセージまでのすべてのメッセージが確認応答され、信頼性のあるメッセージ・シーケンスが終了し、すべてのリソースが開放されます。識別しない場合、シーケンスは、構成したシーケンスの有効期限に達した後で自動的に終了します。

例:

import weblogic.wsee.reliability2.api.WsrmClientFactory;
import weblogic.wsee.reliability2.api.WsrmClient;
...
_service = new BackendReliableServiceService();
...
features.add(... some features ...);
_features = features.toArray(new WebServiceFeature[features.size()]);
...
BackendReliableService anotherPort =
_service.getBackendReliableServicePort(_features);
...
WsrmClient rmClient = WsrmClientFactory.getWsrmClientFromPort(anotherPort);
...
anotherPort.doSomething("One potato");
anotherPort.doSomething("Two potato");
anotherPort.doSomething("Three potato");
// Indicate this next invoke marks the 'final' message for the sequence
rmClient.setFinalMessage();
anotherPort.doSomething("Four");
...

信頼性のあるシーケンスを閉じる

信頼性のあるメッセージング・シーケンスを閉じるには、weblogic.wsee.reliability2.api.WsrmClient.closeMessage()を使用します。

注意:

このメソッドはWS-ReliableMessaging 1.1に対してのみ有効です。WS-ReliableMessaging 1.0ではサポートされていません。

信頼性のあるメッセージング・シーケンスを閉じると、新しいメッセージはRM宛先で受け付けられなくなり、RM送信元で送信されなくなります。閉じられたシーケンスは、まだ、RM宛先によって追跡され、確認応答リクエストに対応します。RM送信元は、シーケンスを終了する前に、信頼性のあるメッセージ・シーケンスの完全な会計情報を取得できます。

注意: シーケンスを閉じるのは、最後の手段と考える必要があり、すべてのリクエストを受信することがないと予想される信頼性のあるメッセージング・シーケンスを閉じる準備をするだけです。たとえば、確認応答が済んでいるリクエストの範囲を確認した後(「確認応答済みリクエストの管理」を参照)、クライアントはシーケンスを閉じる必要があると判断し、特定の時間の後で確認応答されていないメッセージのアカウントに対してエラー処理を実行できます。

信頼性のあるメッセージング・シーケンスが閉じられると、シーケンスの終了はクライアントに委ねられます。構成したタイムアウトに到達した後は、サーバーによって自動的に終了されなくなります。「信頼性のあるシーケンスの終了」を参照してください。

例:

import weblogic.wsee.reliability2.api.WsrmClientFactory;
import weblogic.wsee.reliability2.api.WsrmClient;
...
_service = new BackendReliableServiceService();
...
features.add(... some features ...);
_features = features.toArray(new WebServiceFeature[features.size()]);
...
BackendReliableService anotherPort =
_service.getBackendReliableServicePort(_features);
...
WsrmClient rmClient = WsrmClientFactory.getWsrmClientFromPort(anotherPort);
...
anotherPort.doSomething("One potato");
anotherPort.doSomething("Two potato");
// ... Wait some amount of time, and check for acks
// ... using WsrmClient.getAckRanges() ...
// ... If we don't find all of our acks ...
rmClient.closeSequence();
// ... Do some error recovery like telling our
// ... client we couldn't deliver all requests ...
rmClient.terminateSequence();
...

信頼性のあるシーケンスの終了

これはお薦めできませんが、weblogic.wsee.reliability2.api.WsrmClient.terminateSequence()メソッドを使用すると、すべてのメッセージが確認応答されているかどうかに関係なく、信頼性のあるメッセージ・シーケンスを終了できます。

注意:

代わりに、setFinalMessage()メソッドを使用して、信頼性のあるシーケンスの最後のメッセージを識別することをお薦めします。最後のメッセージを識別すると、最後のメッセージまでのすべてのメッセージが確認応答され、信頼性のあるメッセージ・シーケンスが終了し、すべてのリソースが開放されます。詳細は、「信頼性のあるシーケンスでの最後のメッセージの識別」を参照してください。

シーケンスを終了すると、RM送信元とRM宛先は、そのシーケンスに関連付けられているすべての状態を削除します。クライアントは、終了されたシーケンスに対してはいかなるアクションも実行できなくなります。シーケンスが終了されると、サーバー側の再試行(SAFエージェント)によってシーケンスに対して配信された保留中のリクエストは破棄され、ReliablityErrorListenerで通知として送信されます。

例:

import weblogic.wsee.reliability2.api.WsrmClientFactory;
import weblogic.wsee.reliability2.api.WsrmClient;
...
_service = new BackendReliableServiceService();
...
features.add(... some features ...);
_features = features.toArray(new WebServiceFeature[features.size()]);
...
BackendReliableService anotherPort =
_service.getBackendReliableServicePort(_features);
...
WsrmClient rmClient = WsrmClientFactory.getWsrmClientFromPort(anotherPort);
...
anotherPort.doSomething("One potato");
anotherPort.doSomething("Two potato");
// ... Wait some amount of time, and check for acks
// ... using WsrmClient.getAckRanges() ...
// ... If we don't find all of our acks ...
rmClient.closeSequence();
// ... Do some error recovery like telling our
// ... client we couldn't deliver all requests ...
rmClient.terminateSequence();
...

新しいメッセージ・シーケンスを開始するためのクライアントのリセット

信頼性のあるシーケンスが閉じられて、保持する必要のなくなった信頼性のあるメッセージングに関係のあるすべてのRequestContextプロパティをクリアするには、weblogic.wsee.reliability2.api.WsrmClient.reset()メソッドを使用します。通常、このメソッドは、同じクライアントから信頼性のあるメッセージの別のシーケンスを開始するときに呼び出します。

reset()の使用例については、例B-1「信頼性のあるメッセージングのバッチ化のためのクライアント・ラッパー・クラスの例」を参照してください。

Webサービスの信頼性のあるメッセージングの監視

管理コンソールを使用して、Webサービスまたはクライアントの信頼性のあるメッセージング・シーケンスを監視できます。信頼性のあるメッセージング・シーケンスごとに、シーケンスの状態や送信元サーバーと宛先サーバーなどの、実行時監視情報が表示されます。「この表のカスタマイズ」をクリックすることで、表に表示される情報をカスタマイズできます。

具体的には、監視ページを使用して次のことを特定できます。

- 適切なタイミングでシーケンスをクリーンアップしているかどうか。監視タブに多数のシーケンスが表示される場合、クライアントのコードを調べて原因を特定します。

- 個別のシーケンスに確認応答されていないリクエストがあるか、または予想されるレスポンスを受信していないか。

Webサービスの信頼性のあるメッセージング・シーケンスを監視するには、左ペインの「デプロイメント」ノードをクリックし、右ペインに表示される「デプロイメント」表でWebサービスがパッケージ化されているエンタープライズ・アプリケーションを探します。「+」ノードをクリックしてアプリケーションを展開すると、「Webサービス」カテゴリにアプリケーション内のWebサービスのリストが表示されます。Webサービス名をクリックし、「監視」→「ポート」→「信頼性のあるメッセージング」を選択します。

Webサービス・クライアントの信頼性のあるメッセージング・シーケンスを監視するには、左ペインの「デプロイメント」ノードをクリックし、右ペインに表示される「デプロイメント」表でWebサービス・クライアントがパッケージ化されているエンタープライズ・アプリケーションを探します。「+」ノードをクリックしてアプリケーションを展開し、Webサービス・クライアントが存在するアプリケーション・モジュールをクリックします。「監視」タブをクリックし、「Webサービス・クライアント」タブをクリックします。次に、「監視」→「サーバー」→「信頼性のあるメッセージング」をクリックします。

ビジネス作業単位へのメッセージのグループ化(バッチ化)

多くの場合、Webサービス・クライアントとサービスの間を流れるメッセージは、単一のビジネス・トランザクションつまり作業単位の一部です。たとえば、旅行代理店、航空会社、ホテル、レンタカー会社の間でメッセージを必要とする旅行代理店の予約処理などです。2つのエンドポイントの間を流れるすべてのメッセージはビジネス作業単位と考えることができます。

メッセージをRMシーケンスにグループ化することで、作業単位に関連のあるメッセージを処理するように信頼性のあるメッセージングを調整します。作業単位(つまりシーケンス)の全体がまとめて処理され、エラー・リカバリなどをシーケンス全体に適用できます(http://docs.oasis-open.org/ws-rx/wsrm/200702にあるWS-ReliableMessaging 1.2の仕様(2009年2月)でIncompleteSequenceBehavior要素の説明を参照)。たとえば、シーケンスのギャップの後で発生したリクエストを破棄したり、シーケンスから欠落したリクエストがある場合はリクエストのシーケンス全体を破棄したりするように、RMシーケンスを構成できます。

単位の最初のメッセージを送信する前に新しいクライアント・インスタンスを作成し、単位の最後のメッセージの後でクライアント・インスタンスを破棄することで、メッセージがビジネス作業単位の一部であることを示すことができます。または、WsrmClient API(クライアント・インスタンスをWsrmClientFactory.getWsrmClientFromPort()メソッドに渡すことで取得します)を使用して、シーケンス内の最後のリクエストが送信されようとしていることを示すことができます。これは、クライアント・インスタンスで呼出しを実行する直前にWsrmClient.setFinalMessage()を呼び出すことで行います(「信頼性のあるシーケンスでの最後のメッセージの識別」を参照)。

RMプロトコルには大きなオーバーヘッドが伴います。具体的には、シーケンスの作成と終了では、サービス(RM宛先)との間で往復メッセージが交換されます。つまり、RMシーケンスを確立して終了するには、4つのメッセージをやり取りする必要があります。このため、単一のRMシーケンス上の単一のビジネス作業単位内でリクエストを送信することには利点があります。これにより、RMプロトコルのオーバーヘッドのコストを複数のビジネス・メッセージに分割できます。

場合によっては、信頼性のあるサービスへの通信に使用されているクライアント・インスタンスは、メッセージの所属先のビジネス作業単位の固有概念がない環境で実行されます。その一例は、メッセージ・ブローカなどの仲介者です。この場合、ブローカは、メッセージ自体のみを認識し、メッセージが送信されているコンテキストを認識しないことがしばしばあります。ブローカは、ビジネス作業単位(またはシーケンス)の開始と終了の境界を定めるために何も実行しない場合があります。その結果、リクエストの送信に信頼性のあるメッセージングを使用するとき、ブローカは、送信するすべてのメッセージのRMシーケンス作成および終了プロトコルのオーバーヘッドを負担します。これは、パフォーマンスに重大な負の影響を及ぼす可能性があります。

組込みのビジネス作業単位がメッセージに対して不明の場合は、任意のグループ(バッチ)・メッセージを選択して、恣意的に作成した作業単位(バッチと呼ばれます)に含めることができます。信頼性のあるメッセージをバッチ化すると、前記のパフォーマンスに対する影響を回避でき、信頼性のあるメッセージングのクライアントとサービスの間のネットワーク使用とスループットを調整して最適化できます。関連のないリクエストを小さい単位(約10個のリクエスト)でバッチ化すると、クライアントとサービスの間のスループットが、信頼性のあるメッセージングを使用する(小さいメッセージを送信する)ときの3倍になる場合があることがテストにより示されました。

注意:

すでにビジネス作業単位と関連付けられているリクエストをバッチ化することはお薦めしません。これは、RMシーケンスの境界と作業単位の境界が一致しない場合、エラー・リカバリが複雑になる可能性があるためです。たとえば、ReliabilityErrorListenerを(WsrmClientInitFeatureを使用して)クライアント・インスタンスに追加すると(「信頼性エラー・リスナーの実装」を参照)、このリスナーを使用してシーケンス内の単一のリクエストまたはシーケンス全体の障害に対するエラー・リカバリを実行できます。リクエストをバッチ化する場合、リクエストの障害を適切に処理するために、各リクエストに関する何らかの情報を、このエラー・リカバリ・ロジックで格納する必要があります。バッチ化を行わないクライアントのほうが、それが属しているビジネス作業単位に基づいて、リクエストに関するコンテキストをより多く保持する可能性があります。

次のコード例では、RMリクエストのバッチ化を簡単かつ効率的にするために使用できるBatchingRmClientWrapperという名前のクラスの例を示します。このクラスは、リクエストを指定した数のリクエストのグループにバッチ化します。通常のクライアント・インスタンスに代わる動的なプロキシを作成できます。クライアント・インスタンスで呼び出すと、バッチ・ラッパーが発信リクエストをバッチにシームレスにグループ化し、各バッチに専用のRMシーケンスを割り当てます。バッチ・ラッパーは、特定のバッチの最大存続期間を示す期間指定も取得します。これにより、バッチを完全に満たすのに十分な発信リクエストがない場合でも、完了していないバッチを適切なタイミングで完了させることができます。バッチが指定されている最大存続期間のあいだ存在している場合、バッチの最後のメッセージが送信された場合と同じように閉じられます。

信頼性のあるメッセージングをバッチ化するために使用できるクライアント・ラッパー・クラスの例は、付録B「Example Client Wrapper Class for Batching Reliable Messages」を参照してください。必要であれば、このクラスを独自のアプリケーション・コードとして使用できます。

例6-2 作業単位へのメッセージのグループ化の例(バッチ化)

import java.io.IOException;
import java.util.*;
import java.util.*;

import javax.servlet.*;
import javax.xml.ws.*;

import weblogic.jws.jaxws.client.ClientIdentityFeature;
import weblogic.jws.jaxws.client.async.AsyncClientHandlerFeature;
import weblogic.jws.jaxws.client.async.AsyncClientTransportFeature;
import weblogic.wsee.reliability2.api.ReliabilityErrorContext;
import weblogic.wsee.reliability2.api.ReliabilityErrorListener;
import weblogic.wsee.reliability2.api.WsrmClientInitFeature;

/**
* Example client for invoking a reliable Web service and 'batching' requests
* artificially into a sequence. A wrapper class called
* BatchingRmClientWrapper is called to begin and end RM sequences for each batch of
* requests. This avoids per-message RM sequence handshaking
* and termination overhead (delivering better performance).
*/
public class BestPracticeAsyncRmBatchingClient
extends GenericServlet {

private BackendReliableServiceService _service;
private BackendReliableService _singletonPort;
private BackendReliableService _batchingPort;

private static int _requestCount;
private static String _lastResponse;

@Override
public void init()
throws ServletException {

_requestCount = 0;
_lastResponse = null;

// Only create the Web service object once as it is expensive to create repeatedly.
if (_service == null) {
_service = new BackendReliableServiceService();
}

// Best Practice: Use a stored list of features, per client ID, to create client instances.
// Define all features for the Web service port, per client ID, so that they are
// consistent each time the port is called. For example:
// _service.getBackendServicePort(_features);

List<WebServiceFeature> features = new ArrayList<WebServiceFeature>();

// Best Practice: Explicitly define the client ID.
ClientIdentityFeature clientIdFeature =
new ClientIdentityFeature("MyBackendServiceAsyncRmBatchingClient");
features.add(clientIdFeature);

// Best Practice: Always implement a reliability error listener.
// Include this feature in your reusable feature list. This enables you to determine
// a reason for failure, for example, RM cannot deliver a request or the RM sequence fails in
// some way (for example, client credentials refused at service).
WsrmClientInitFeature rmFeature = new WsrmClientInitFeature();
features.add(rmFeature);
rmFeature.setErrorListener(new ReliabilityErrorListener() {
public void onReliabilityError(ReliabilityErrorContext context) {
// At a *minimum* do this
System.out.println("RM sequence failure: " +
context.getFaultSummaryMessage());
_lastResponse = context.getFaultSummaryMessage();
}
});

// Asynchronous endpoint
AsyncClientTransportFeature asyncFeature =
new AsyncClientTransportFeature(getServletContext());
features.add(asyncFeature);

// Best Practice: Define a port-based asynchronous callback handler,
// AsyncClientHandlerFeature, for asynchronous and dispatch callback handling.
BackendReliableServiceAsyncHandler handler =
new BackendReliableServiceAsyncHandler() {
public void onDoSomethingResponse(Response<DoSomethingResponse> res) {
// ... Handle Response ...
try {
DoSomethingResponse response = res.get();
_lastResponse = response.getReturn();
System.out.println("Got reliable/async/batched response: " + _lastResponse);
} catch (Exception e) {
_lastResponse = e.toString();
e.printStackTrace();
}
}
};
AsyncClientHandlerFeature handlerFeature =
new AsyncClientHandlerFeature(handler);
features.add(handlerFeature);

// Set the features used when creating clients with
// this client ID "MyBackendServiceAsyncRmBatchingClient"

WebServiceFeature[] featuresArray =
features.toArray(new WebServiceFeature[features.size()]);

// Best Practice: Define a singleton port instance and initialize it when
// the client container initializes (upon deployment).
// The singleton port will be available for the life of the servlet.
// Creation of the singleton port triggers the asynchronous response endpoint to be published
// and it will remain published until our container (Web application) is undeployed.
// Note, we will get a call to destroy() before this.
_singletonPort = _service.getBackendReliableServicePort(featuresArray);

// Create a wrapper class to 'batch' messages onto RM sequences so
// a client with no concept of which messages are related as a unit can still achieve
// good performance from RM. The class will send a given number of requests on
// the same sequence, and then terminate that sequence before starting
// another to carry further requests. A batch has both a max size and
// lifetime so no sequence is left open for too long.
// The example batches 10 messages or executes for 20 seconds, whichever comes
// first. Assuming there were 15 total requests to send, the class would start and complete
// one full batch of 10 requests, then send the next batch of five requests.
// Once the batch of five requests has been open for 20 seconds, it will be closed and the
// associated sequence terminated (even though 10 requests were not sent to fill the batch).
BackendReliableService batchingPort =
_service.getBackendReliableServicePort(featuresArray);
BatchingRmClientWrapper<BackendReliableService> batchingSeq
= new BatchingRmClientWrapper<BackendReliableService>(batchingPort,
BackendReliableService.class,
10, "PT20S",
System.out);
_batchingPort = batchingSeq.createProxy();
}

@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {

// TODO: ... Read the servlet request ...

// For this simple example, echo the _lastResponse captured from
// an asynchronous DoSomethingResponse response message.

if (_lastResponse != null) {
res.getWriter().write(_lastResponse);
System.out.println("Servlet returning _lastResponse value: " + _lastResponse);
_lastResponse = null; // Clear the response so we can get another
return;
}

// Synchronize on _batchingPort since it is a class-level variable and it might
// be in this method on multiple threads from the servlet engine.

synchronized(_batchingPort) {

// Use the 'batching' port to send the requests instead of creating a
// new request each time.
BackendReliableService port = _batchingPort;

// Set the endpoint address for BackendService.
((BindingProvider)port).getRequestContext().
put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"http://localhost:7001/BestPracticeReliableService/BackendReliableService");

// Make the invocation. Our asynchronous handler implementation (set
// into the AsyncClientHandlerFeature above) receives the response.
String request = "Protected and serve " + (++_requestCount);
System.out.println("Invoking DoSomething reliably/async/batched with request: " +
request);
port.doSomethingAsync(request);
}

// Return a canned string indicating the response was not received
// synchronously. Client needs to invoke the servlet again to get
// the response.
res.getWriter().write("Waiting for response...");
}

@Override
public void destroy() {

try {
// Best Practice: Explicitly close client instances when processing is complete.
// Close the singleton port created during initialization. Note, the asynchronous
// response endpoint generated by creating _singletonPort *remains*
// published until our container (Web application) is undeployed.
((java.io.Closeable)_singletonPort).close();
// Best Practice: Explicitly close client instances when processing is complete.
// Close the batching port created during initialization. Note, this will close
// the underlying client instance used to create the batching port.
((java.io.Closeable)_batchingPort).close();

// Upon return, the Web application is undeployed, and the asynchronous
// response endpoint is stopped (unpublished). At this point,
// the client ID used for _singletonPort will be unregistered and will no longer be
// visible from the Administration Console and WLST.
} catch (Exception e) {
e.printStackTrace();
}
}
}

信頼性のあるWebサービスを再デプロイする際にクライアント側で考慮すべき事項

WebLogic Serverでは、本番用の再デプロイメントがサポートされています。つまり、信頼性のあるWebLogic Webサービスの更新後の新しいバージョンを、同じWebサービスの古いバージョンと並行してデプロイできます。

WebLogic Serverでは、新しいクライアントのリクエストのみが新しいバージョンに転送されるように、クライアント接続が自動的に管理されます。再デプロイメント時にすでにWebサービスに接続していたクライアントは、作業が完了するまで古いバージョンのサービスを使用し続け、作業が完了した時点で古いWebサービスが自動的にリタイアされます。クライアントが信頼性のあるWebサービスに接続されている場合は、既存の信頼性のあるメッセージ・シーケンスがクライアントによって明示的に終了されるか、またはタイムアウトになったときに、そのクライアントの作業が完了したと見なされます。

本番用の再デプロイメントとWebサービス・クライアントの詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebサービスを再デプロイする際にクライアントで考慮すべき事項に関する項を参照してください。

WebLogic Webサービスの信頼性のあるメッセージングとの相互運用性

WebLogic Webサービスの信頼性のあるメッセージングの実装は、IBMおよびMicrosoft .NETの各サードパーティ・ベンダーのWebサービスで提供されるWebサービスの信頼性のあるメッセージングの実装と相互運用できます。Microsoft .NETと相互運用するときのベスト・プラクティスは、『Oracle WebLogic Server WebLogic Webサービスの紹介』のMicrosoft WCF/.NETとの相互運用性に関する項を参照してください。

Webサービスの信頼性のあるメッセージングを使用するOracle SOAサービスとの相互運用性を拡張するには、相互運用性に関する次のガイドラインを考慮してください。

- 非同期トランスポートには接続作成を使用しないでください(「ファイアウォールの内側からの非同期Webサービス・クライアントの使用(接続作成)」を参照)。信頼性のあるSOAサービスは接続作成をサポートしません。

- WS-SecureConversationを使用して信頼性のあるWebサービスを保護しないでください。SOAサービスは、Webサービスの信頼性のあるメッセージングとWS-SecureConversationの併用をサポートしません。

- 信頼性のあるSOAサービスにアクセスする信頼性のあるWebLogic Webサービス・クライアントの場合:

- 同期(匿名WS-Addressing ReplyTo EPR)リクエスト応答または一方向MEP(メッセージ交換パターン)を使用します。

- 非同期(非匿名WS-Addressing ReplyTo EPR)リクエスト応答MEPは使用しないでください。

- 信頼性のあるWebLogic Webサービスにアクセスする信頼性のあるSOAクライアントの場合、次のいずれかを使用します。

- 同期(匿名WS-Addressing ReplyTo EPR)リクエスト応答または一方向MEP。

- 非同期(非匿名WS-Addressing ReplyTo EPR)リクエスト応答MEP。

7 Webサービス永続性の管理

この章では、Java API for XML Web Services (JAX-WS)を使用したWebLogic Webサービスの永続性を管理する方法について説明します。

この章の内容は以下のとおりです。

- Webサービス永続性の概要

- Webサービス永続性を構成する手順

- Webサービス永続性の構成

- クラスタでのWebサービス永続性の使用

- Webサービス永続性のクリーンアップ

Webサービス永続性の概要

WebLogic Serverには、Webサービスに組み込みの高パフォーマンスのストレージ・ソリューションを提供するデフォルトのWebサービス永続性が用意されています。Webサービス永続性は、長時間実行されるリクエストをサポートし、サーバーの再起動があっても存続するように、次の高度な機能で使用されます。

- 非同期クライアント・トランスポートまたは接続作成を使用したWebサービスの非同期呼出し

- Webサービスの信頼性のあるメッセージング

- メッセージ・バッファリング

- WS-SecureConversationを使用したセキュリティ

具体的には、Webサービス永続性は次の種類の情報を保存するために使用されます。

- クライアントのIDとプロパティ

- ヘッダーと本体を含むSOAPメッセージ

- Webサービスまたはクライアントでメッセージを処理するために必要なコンテキスト・プロパティ(非同期メッセージと同期メッセージの両方)

次の図では、Webサービス永続性の構成例を示します。

図7-1 Webサービス永続性の構成例

「図7-1 Webサービス永続性の構成例」の説明

次の表では、前の図で示したWebサービス永続性のコンポーネントについて説明します。

表7-1 Webサービス永続性のコンポーネント

コンポーネント

説明

論理ストア

構成要件を提供し、Webサービスを物理ストアとバッファリング・キューに接続します。

物理ストア

物理ストレージ(ファイルやDBMSなど)のデータを保存および取得するためのI/O操作を処理します。物理ストアとしては、WebLogic Server管理コンソールまたはWLSTを使用して構成されたWebLogic Server永続ストアまたはインメモリー・ストアを使用できます。

注意: WebLogic Server永続ストアを論理ストア用の物理ストアとして使用する場合、リクエストとレスポンスのバッファリング・キューの名前は、バッファリングの構成ではなく、論理ストアの構成から取得されます。

バッファリング・キュー

Webサービスのバッファリングされたリクエストとレスポンスを格納します。

Webサービス永続性を構成するときは、次のものを関連付けます。

- 論理ストアとバッファリング・キュー。

- JMS構成を介して物理ストアと関連付けられたバッファリング・キュー。

論理ストアとバッファリング・キューの間の関連付けを使用して、論理ストアと物理ストアの間の関連付けが推論されます。デフォルトの論理ストアは、WseeStoreという名前で、WebLogic Advanced Web Services for JAX-WS拡張テンプレート(wls_webservice_jaxws.jar)を使用してドメインが作成されるときに自動的に作成されます。デフォルトで、サーバー用に構成された物理ストアは、バッファリング・キューと関連付けられます。これにより、すべてのWebサービス永続性とバッファリングで同じ物理ストアが使用されることが保証されます。単一の物理ストアを使用することで、いっそう効率的な単一フェーズのXAトランザクションが保証され、移行が容易になります。

アプリケーション環境内で使用するための1つ以上の論理ストアを構成できます。表7-1では、サーバーServer1とServer2は同じ論理ストアを使用しています。この構成により、クラスタ内で実行するアプリケーションを、単一のストア名にアクセスするようにグローバルに構成できます。後の「Webサービス永続性の構成」で説明するように、Webサービス永続性をさまざまなレベルで構成して、きめ細かく管理できます。ベスト・プラクティスは「Webサービス永続性を構成する手順」で説明します。

Webサービス永続性を構成する手順

表7-2では、Webサービス永続性を構成してWebサービスの信頼性のあるメッセージングをサポートするためのベスト・プラクティスについて説明します。

表7-2 Webサービス永続性を構成する手順

ベスト・プラクティス

説明

各管理単位(ビジネス単位、部門など)に対する論理ストアを定義します。

異なる論理ストアを定義することで、管理単位ごとのサービスレベル契約をより適切に管理できます。詳細は、「論理ストアの構成」を参照してください。

管理単位に関連する個々のクライアントまたはサービスに対して正しい論理ストアを使用します。

論理ストアは、WebLogic Server、Webサービス、Webサービス・クライアントのいずれかのレベルで構成できます。詳細は、「Webサービス永続性の構成」を参照してください。

論理ストアごとに異なる物理ストアとバッファリング・キューを定義します。

詳細は、「Webサービス永続性の構成の例」を参照してください。

表7-2で定義されているベスト・プラクティスは、保守、障害リカバリ、リソースの移行を容易にします。

たとえば、会社Xが、製造、買掛、売掛などの複数の部門に対するWebサービスを開発しているものとします。ベスト・プラクティスに従うと、会社Xは部門ごとに少なくとも3つの論理ストアを定義します。

さらに、製造部門とIT部門の間には、数分以下のシステム停止を許容できることを指定するサービスレベル契約があるものとします。一方、売掛部門と買掛部門にはさらに緩いサービスレベル契約があり、1時間までのシステム停止は許容されます。Webサービスをホストするシステムと製造部門用のクライアントが使用できなくなった場合、IT部門は、障害から数分以内にこれらのWebサービスとクライアントで必要なリソースを新しいアクティブ・サーバーに移行する必要があります。個別の論理ストアが定義されているため、IT部門は、売掛部門と買掛部門に必要なリソースとは独立して、開発部門の論理ストアと関連付けられているファイル・ストアやJMSサーバーなどを移行できます。

Webサービス永続性の構成

次の表では、Webサービス永続性の各コンポーネントに対して構成できる情報を説明します。

表7-3 Webサービス永続性のコンポーネントの構成の説明

コンポーネント

構成要件の説明

論理ストア

各論理ストアに対して次の情報を構成します。

- 論理ストアの名前。

- ストア内のオブジェクトの最大存続期間。

- ストアから失効したオブジェクトを削除するクリーナ・スレッド。詳細は、「Webサービス永続性のクリーンアップ」を参照してください。

- ネットワーク内の他のサーバーからのアクセス性。

- リクエストとレスポンスのバッファリング・キュー。リクエスト・バッファリング・キューは、関連付けによって物理ストアを類推するために使用されます。

物理ストア

物理ストアに対して次の情報を構成します。

- 物理ストアの名前。

- 種類およびパフォーマンス・パラメータ。

- ストアの場所。

注意: 物理ストアとバッファリング・キューは、両方ではなく、どちらか一方のみを構成します。バッファリング・キューを構成すると、物理ストアの情報は類推されます。

バッファリング・キュー

バッファリング・キューに対して次の情報を構成します。

- リクエストとレスポンスのキューの詳細

- 再試行回数と遅延

次の表で定義されているレベルで、Webサービス永続性を構成できます。

表7-4 Webサービス永続性の構成

レベル

説明

WebLogic Server

サーバー・レベルで構成されたWebサービス永続性では、そのサーバーで実行しているすべてのWebサービスとクライアントのデフォルトの構成を定義します。WebLogic Serverに対してWebサービス永続性を構成するには、次のいずれかの方法を使用します。

- 構成ウィザードを使用してドメインを作成または拡張するときに、WebLogic Advanced Web Services for JAX-WS拡張テンプレート(wls_webservice_jaxws.jar)を適用して、Webサービス永続性をサポートするために必要なリソースを自動的に構成できます。
この拡張テンプレートの使用は必須ではありませんが、使用すると必要なリソースの構成が格段に容易になります。

- Webサービス永続性に必要なリソースを、Oracle WebLogic管理コンソールまたはWLSTを使用して構成します。詳細は、次を参照してください。
- 管理コンソール: Oracle WebLogic Server管理コンソール・ヘルプのWebサービス永続性の構成に関する項

- WLST: Oracle WebLogic Scripting Toolの既存ドメインの構成に関する項

詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』の高度なWeb Services機能のためのドメインの構成に関する項を参照してください。

Webサービス・エンドポイント

Webサービス・エンドポイントによって使用されるデフォルトの論理ストアを構成します(「Webサービス・エンドポイントのWebサービス永続性の構成」を参照)。

Webサービス・クライアント

Webサービス・クライアントによって使用されるデフォルトの論理ストアを構成します(「Webサービス・クライアントのWebサービス永続性の構成」を参照)。

次の項では、Webサービス永続性の構成について詳細に説明します。

- 論理ストアの構成

- Webサービス・エンドポイントのWebサービス永続性の構成

- Webサービス・クライアントのWebサービス永続性の構成

論理ストアの構成

アプリケーション環境内で使用する1つ以上の論理ストアを構成し、デフォルトとして使用する論理ストアを指定できます。

デフォルトの論理ストアWseeStoreは、WebLogic Advanced Web Services for JAX-WS拡張テンプレート(wls_webservice_jaxws.jar)を使用してドメインを作成または拡張するときに、自動的に生成されます(『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebサービスの高度な機能のためのドメインの構成に関する項を参照)。

管理コンソールを使用して論理ストアを構成できます(Oracle WebLogic Server管理コンソール・ヘルプのWebサービス永続性の構成に関する項を参照)。または、WLSTを使用してリソースを構成できます。WLSTを使用してドメインを拡張する方法の詳細は、Oracle WebLogic Scripting Toolの既存ドメインの構成に関する項を参照してください。

次の表では、論理ストアに対して定義できるプロパティを説明します。

表7-5 論理ストアの構成プロパティ

プロパティ

説明

論理ストア名

論理ストアの名前。名前はアルファベット文字から始める必要があり、アルファベット文字、スペース、ダッシュ、アンダースコア、数字のみを使用できます。

このフィールドのデフォルトはLogicalStore_nです。このフィールドは必須です。

Webサービス拡張テンプレートを使用して単一のサーバー・ドメインを作成または拡張する場合は、WseeStoreという名前の論理ストアがデフォルトで作成されます。

デフォルト論理ストア

サーバー上のすべてのWebサービスの状態を永続化するためにデフォルトで使用する論理ストアかどうかを指定するフラグ。

デフォルトとして設定できる論理ストアは1つだけです。現在の論理ストアでこのフラグを有効にした場合、現在のデフォルト・ストアではフラグが無効になります。

永続性方式

永続性の方式です。ドロップダウン・メニューから次のいずれかの値を選択します。

- ローカル・アクセスのみ: ローカル・サーバーだけがアクセスできます。

- メモリー内: ローカルVMのみがアクセスできます。この場合、バッファリング・キューと物理ストアの構成情報は無視されます。

リクエスト・バッファリング・キューのJNDI名

リクエスト・バッファリング・キューのJNDI名。リクエスト・バッファリング・キューは、関連付けによって物理ストアを類推するために使用されます。このプロパティを設定しない場合、サーバーに対して構成されているデフォルトの物理ストアが使用されます。

注意: 物理ストアとバッファリング・キューは、両方ではなく、どちらか一方のみを構成します。バッファリング・キューを構成すると、物理ストアの情報は類推されます。

より効率的な単一フェーズのXAトランザクションを可能にし、サービスの移行を容易にするため、永続状態とメッセージ・バッファリングの両方で同じ物理ストレージ・リソースを使用することをお薦めします。この値を設定することで、バッファリング・キューと物理ストアが同じ物理ストレージ・リソースを参照することが保証されます。

Webサービス拡張テンプレートを使用してドメインを作成または拡張する場合は、weblogic.wsee.RequestBufferedRequestQueueという名前のバッファリング・キューがデフォルトで作成されます。

注意: 「永続性方式」を「メモリー内」に設定すると、このプロパティは無視されます。

レスポンス・バッファリング・キューのJNDI名

レスポンス・バッファリング・キューのJNDI名。

このプロパティを設定しない場合は、「リクエスト・バッファリング・キューのJNDI名」プロパティで定義されているリクエスト・キューが使用されます。

Webサービス拡張テンプレートを使用してドメインを作成または拡張する場合は、weblogic.wsee.RequestBufferedRequestErrorQueueという名前のバッファリング・キューがデフォルトで作成されます。

注意: 「永続性方式」を「メモリー内」に設定すると、このプロパティは無視されます。

クリーナの間隔

論理ストアをクリーンアップする間隔。詳細は、「Webサービス永続性のクリーンアップ」を参照してください。

指定する値はXMLスキーマの期間を表す字句形式(PnYnMnDTnHnMnS)に従った正の値でなければなりません。ここで、nYは年数、nMは月数、nDは日数を表し、Tは日付/時刻のセパレータ、nHは時間数、nMは分数、nSは秒数を表します。この値のデフォルトはPT10M (10分)です。

注意: このフィールドは、論理ストアを編集するときにのみ使用できます。論理ストアを作成するときは、このフィールドはデフォルトでPT10M(10分)に設定されます。

デフォルト最大オブジェクト存続期間

オブジェクトの最大存続期間として使用されるデフォルト値。この値は、論理ストアに保存される個別のオブジェクトでオーバーライドできます。

指定する値はXMLスキーマの期間を表す字句形式(PnYnMnDTnHnMnS)に従った正の値でなければなりません。ここで、nYは年数、nMは月数、nDは日数を表し、Tは日付/時刻のセパレータ、nHは時間数、nMは分数、nSは秒数を表します。この値のデフォルトはP1D (1日)です。

注意: このフィールドは、論理ストアを編集するときにのみ使用できます。論理ストアを作成するときは、このフィールドはデフォルトでP1D(1日)に設定されます。

Webサービス・エンドポイントのWebサービス永続性の構成

デフォルトでは、Webサービス・エンドポイントはサーバーに対して定義されているWebサービス永続ストアを使用します。Webサービス・エンドポイントによって使用される論理ストアは、管理コンソールを使用してオーバーライドできます。詳細は、Oracle WebLogic Server管理コンソール・ヘルプのWebサービス永続性の構成に関する項を参照してください。

Webサービス・クライアントのWebサービス永続性の構成

Webサービス・クライアントの永続性の構成の詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebサービス・クライアントの構成に関する項を参照してください。

クラスタでのWebサービス永続性の使用

クラスタでWebサービス永続性を使用するための考慮事項を次に示します。

- WebLogic Advanced Web Services for JAX-WS拡張テンプレート(wls_webservice_jaxws.jar)を使用してクラスタ・ドメインを作成または拡張する場合、クラスタでWebサービス永続性をサポートするために必要なリソースが自動的に作成されます。詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』の高度なWebサービス機能用のドメインの構成に関する項を参照してください。

- サービスの移行を容易にするため、永続状態とメッセージ・バッファリングの両方に同じ物理ストレージ・リソースを使用することをお薦めします。バッファリング・キューと物理ストアが同じ物理ストレージ・リソースを参照するようにするには、「論理ストアの構成」で説明されているように、論理ストアの「リクエスト・バッファリング・キューのJNDI名」プロパティを構成します。

- バッファリング・キューはJMS Uniform Distributed Destination(UDD)として定義することをお薦めします。JMSでは、指定する各JMSサーバーのUDDにメンバー・キューが定義されます。論理ストアは定義されているバッファリング・キューによって物理ストアと関連付けられるので、これにより、サービスの移行の間に、論理ストアは、新しいサーバーに移行されるメンバー・キューの新しい物理ストアをシームレスに使用できます。

- JMSサーバー、Store-And-Forward(SAF)サービス・エージェント、物理ストア(ファイル・ストア)リソースを移行可能なターゲットにすることをお薦めします。詳細については、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』の高度なWebサービス機能で必要なリソースに関する項を参照してください。

たとえば、図7-2で示されている2ノードのクラスタ構成を考えます。ドメイン・リソースは、前記のガイドラインを使用して構成およびターゲット指定されます。

図7-2 2ノード・クラスタ構成の例(移行前)

「図7-2 2ノード・クラスタ構成の例(移行前)」の説明

次の図では、Server1で障害が発生した場合にServer1上のリソースをServer2に簡単に移行する方法を示します。

図7-3 2ノード・クラスタ構成の例(移行後)

「図7-3 2ノード・クラスタ構成の例(移行後)」の説明

Webサービス永続性のクリーンアップ

永続化された情報は、期限切れまたは失効したオブジェクトを削除するために、定期的にクリーンアップされます。通常、オブジェクトは特定の有効期限または最大存続期間と関連付けられています。さらに、失効したオブジェクトは、レスポンスを受信しなかったリクエスト、または明示的に終了されなかった信頼性のあるメッセージング・シーケンスを表す場合があります。

Webサービス永続性がクリーンアップされる間隔は、論理ストアの「クリーナの間隔」構成プロパティで構成します。このプロパティの設定の詳細は、「論理ストアの構成」を参照してください。

8 Webサービスのメッセージ・バッファリングの構成

この章では、Java API for XML Web Services(JAX-WS)を使用したWebLogic Webサービスのメッセージ・バッファリングを構成する方法について説明します。

この章の内容は以下のとおりです。

- メッセージ・バッファリングの概要

- メッセージ・バッファリングの構成

メッセージ・バッファリングの概要

バッファリングされたWebサービス上の操作が呼び出されると、その呼出しを表すメッセージがJMSキューに格納されます。WebLogic Serverは、このバッファリングされたメッセージを非同期に処理します。メッセージがまだキュー内にある間にWebLogic Serverがダウンした場合、WebLogic Serverが再起動するとすぐに処理されます。

WebLogic Serverは、あらかじめ構成されて管理されたスレッドのプールから取得した別のスレッドで、リクエスト・メッセージを処理します。これにより、WebLogic Serverはクライアントの負荷のスパイクを緩和し、リクエストの時間順の処理を続けることができます。メッセージ・バッファリングは、サービス拒否攻撃とサーバーでの一般的な過負荷状態を防ぐための強力なツールです。

Webサービスにメッセージ・バッファリングを構成するかどうかを判断するための参考に、「バッファなしの信頼性のあるWebサービスでの障害シナリオ」を確認することをお薦めします。

メッセージ・バッファリングの構成

WebLogic ServerまたはWebサービス・エンドポイントのレベルで、Webサービスにメッセージ・バッファリングを構成できます。サーバー・レベルで構成されたメッセージ・バッファリングでは、Webサービス・エンドポイント・レベルで明示的にオーバーライドされない限り、そのサーバー上で実行するすべてのWebサービスとクライアントに対するデフォルトのメッセージ・バッファリングが定義されます。

WebLogic Server管理コンソールを使用してWebLogic ServerまたはWebサービス・エンドポイントのレベルでWebサービスに対するメッセージ・バッファリングを構成する詳細な手順は、Oracle WebLogic Server管理コンソール・ヘルプのWebサービスに対するメッセージ・バッファリングの構成に関する項を参照してください。

Webサービス・エンドポイント・レベルでメッセージ・バッファリングを構成するときは、「バッファリング構成のカスタマイズ」を選択し、Webサービス記述子またはデプロイメント・プランで定義されているバッファリング構成をWebサービス・エンドポイント・レベルでカスタマイズすることを指定します。これを選択しないと、WebLogic Serverレベルで指定されているバッファリング構成が使用されます。

または、WLSTを使用して、メッセージ・バッファリングを構成することもできます。WLSTを使用したドメインの拡張の詳細は、『Oracle WebLogic Scripting Tool』の既存ドメインの構成に関する項を参照してください。

次の項では、メッセージ・バッファリングの構成プロパティについて説明します。

- リクエスト・キューの構成

- レスポンス・キューの構成

- メッセージの再試行回数と遅延の構成

リクエスト・キューの構成

次の表では、リクエスト・キューの構成に使用するプロパティを説明します。

表8-1 リクエスト・キューの構成

プロパティ

説明

リクエスト・キューの有効化

リクエスト・キューが有効かどうかを指定するフラグ。デフォルトでは、リクエスト・キューは無効です。リクエスト・キューの名前は、そのレベルで有効な論理ストアによって定義されます。

WebLogic Server永続ストアを論理ストアの物理ストアとして使用すると、リクエスト・バッファリング・キューとレスポンス・バッファリング・キューの名前はバッファリングの構成ではなく論理ストアの構成から取得されます。

リクエスト・キューの接続ファクトリのJNDI名

リクエスト・メッセージ・バッファリングに使用する接続ファクトリのJNDI名。この値のデフォルトは、サーバーで定義されているデフォルトのJMS接続ファクトリです。

リクエスト・キュー・トランザクションの有効化

リクエスト・バッファリング・キューのメッセージを格納および取得するときにトランザクションを使用するかどうかを指定するフラグ。デフォルトはfalseです。

レスポンス・キューの構成

次の表では、レスポンス・キューの構成に使用するプロパティを説明します。

表8-2 レスポンス・キューの構成

プロパティ

説明

レスポンス・キューの有効化

レスポンス・キューが有効かどうかを指定するフラグ。デフォルトでは、レスポンス・キューは無効です。レスポンス・キューの名前は、そのレベルで有効な論理ストアによって定義されます。

WebLogic Server永続ストアを論理ストアの物理ストアとして使用すると、リクエスト・バッファリング・キューとレスポンス・バッファリング・キューの名前はバッファリングの構成ではなく論理ストアの構成から取得されます。

レスポンス・キューの接続ファクトリのJNDI名

レスポンス・メッセージ・バッファリングに使用する接続ファクトリのJNDI名。この値のデフォルトは、サーバーで定義されているデフォルトのJMS接続ファクトリです。

レスポンス・キュー・トランザクションの有効化

レスポンス・バッファリング・キューのメッセージを格納および取得するときにトランザクションを使用するかどうかを指定するフラグ。デフォルトはfalseです。

メッセージの再試行回数と遅延の構成

次の表では、メッセージの再試行回数と遅延の構成に使用するプロパティを説明します。

表8-3 メッセージの再試行回数と遅延の構成

プロパティ

説明

再試行回数

呼び出されたWebLogic ServerインスタンスのJMSキューが、操作が正常に呼び出されるまでWebサービスの実装にメッセージの配信を試みる回数。デフォルト値は3です。

再試行の遅延

バッファリングされたリクエストとレスポンスの再試行の間隔。この値は、「再試行回数」が0より大きいときにのみ適用されます。

指定する値はXMLスキーマの期間を表す字句形式(PnYnMnDTnHnMnS)に従った正の値でなければなりません。ここで、nYは年数、nMは月数、nDは日数を表し、Tは日付/時刻のセパレータ、nHは時間数、nMは分数、nSは秒数を表します。この値のデフォルトはP0DT30S (30秒)です。

9 クラスタ内のWebサービスの管理

この章では、クラスタ内のWebLogic Webサービスの管理方法について説明します。

この章の内容は以下のとおりです。

- Webサービス・クラスタでのルーティングの概要

- クラスタでのルーティングのシナリオ

- Webサービス・クラスタでのルーティングの仕組み

- クラスタ内のWebサービスの構成

- クラスタのルーティング・パフォーマンスのモニター

注意:

クラスタでのWebサービス永続性の使用に関する考慮事項は、「クラスタでのWebサービス永続性の使用」を参照してください。

Webサービス・クラスタでのルーティングの概要

ステートレスWebサービス(それまでの起動における状態情報を認識している必要のないサービス)のクラスタリングは単純であり、サード・パーティのHTTPロード・バランサに対して既存のWebLogic HTTPルーティング機能と連携して動作します。

状態情報のメンテナンスが必要なWebサービスのクラスタリングには課題がいくつかあります。そのようなWebサービスの各インスタンスは状態情報に関連付けられており、この状態情報を管理し、保持する必要があります。クラスタでのルーティングの決定は、メッセージがクラスタ内の特定のサーバーにバインドされているかどうかに基づいて行われます。たとえば、メッセージの処理に必要な状態情報が特定のサーバーに格納されいる場合、その状態情報はそのサーバーでローカルに使用することしかできません。

注意:

セッション状態レプリケーションを使用して状態を管理するサービスは、Reliable Secure ProfileのようなWebサービスの高度な機能を利用するサービスとは問題の種類が異なります。後者では、ローカル・サーバーのみで利用できる状態の格納を備えるなど、永続性に関してより堅牢なアプローチが必要です。詳細は、「永続性に関する注意」を参照してください。

Webサービス・リクエストが適切なサーバーにルーティングされるようにするだけでなく、クラスタリングに関する次の一般的な要件を満たす必要があります。

- クラスタの内部トポロジは、クライアントに対して透過的にする必要があります。クライアントは、フロントエンド・ホストのみを介してクラスタと相互通信するため、クラスタ内の特定のサーバーを認識する必要はありません。これによって、クラスタは時間をかけて拡張し、需要を満たすことができます。

- クラスタの移行がクライアントに対して透過的に行われることが必要です。クラスタ内のリソース(永続ストアなど、WebサービスまたはWebサービス・クライアントに必要なリソース)は、クラスタの拡大や障害対応などの理由で、あるサーバーから別のサーバーへ移行できます。

クラスタ内のWebサービスのルーティングについては、前述の要件に合せて、次の方式が用意されています。

- インプレースSOAPルーター: リクエスト・メッセージが正しいサーバーに届き、そうでない場合は正しいサーバーに転送されることを前提としています(追加ホップは最大1回)。ルーティングの決定は、メッセージを受信するWebサービスが行います。このルーティング方式は実装が最も簡単であり、構成も必要ありません。ただし、次の方式に比べると堅牢性に劣ります。

- フロントエンドSOAPルーター (HTTPクラスタ・サーブレットのみ): メッセージ・ルーティングは、クラスタのかわりにメッセージを受け入れるフロントエンド・ホストによって管理され、クラスタの選択メンバー・サーバーに転送します。Webサービスの場合、フロントエンドSOAPルーターは、SOAPメッセージ内の情報を検査し、メッセージをルーティングする先の正しいサーバーを決定します。
このルーティング方式は構成が複雑ですが、メッセージが適切なサーバーに直接ルーティングされるため効率的です(追加ホップは発生しません)。

注意:

「ファイアウォールの内側からの非同期Webサービス・クライアントの使用(接続作成)」の説明に従って接続作成を使用するとき、所定の接続作成匿名URIに関連するすべてのメッセージの適切なルーティングを保証できるのはフロントエンドSOAPルーティングのみです。

この章では、クラスタ内のWebサービスのルーティングが最適化されるように環境を構成する方法について説明します。フロントエンドSOAPルーターとしてのHTTPクラスタ・サーブレットの使用についても説明します。また、インプレースSOAPルーターを有効化し、HTTPクラスタ・サーブレットが使用できない場合や初期化されていない場合に使用します。

永続性に関する注意

「HTTPセッションを使用したステートフルJAX-WS Webサービスのプログラミング」で説明されているように、一部のケースではHttpSessionを使用してWebサービスの状態を維持できますが、この単純な永続性には十分な堅牢性がありません。Webサービスの高度な機能(信頼性のあるメッセージング、接続作成、Secure Conversationなど)では堅牢な永続性が要件となっており、HttpSessionのみを使用して満たすことはできません。Webサービスの高度な機能は、論理ストアという概念に基づいた専用の永続性実装を使用します。詳細は、「Webサービス永続性の管理」を参照してください。

現時点では、Webサービス状態の永続性に関するこの2つのアプローチには互換性がありません。HttpSession永続性を使用するクラスタ化ステートフルWebサービスの作成を選択してから、(クライアントまたはサービスとして)そのサービスでWebサービスの高度な機能を使用すると、クラスタにおけるサービスの正常な動作が保証されません。これは、HttpSessionレプリケーションが、Webサービスの高度な機能の永続性をホストするのではなく、様々なサーバー・セットでHttpSessionを使用可能にできるためです。

クラスタでのルーティングのシナリオ

次の項では、クラスタ環境内でWebサービスのリクエスト・メッセージとレスポンス・メッセージをルーティングする際のシナリオについて、図を使用して説明します。

- シナリオ1: 単一サーバーへのWebサービス・レスポンスのルーティング

- シナリオ2: ルーティング情報を使用した単一サーバーへのWebサービス・レスポンスのルーティング

- シナリオ3: IDを使用した単一サーバーへのWebサービス・レスポンスのルーティング

シナリオ1: 単一サーバーへのWebサービス・レスポンスのルーティング

このシナリオでは、受信したリクエストがサーバーに対してロード・バランシングされます。そのリクエストへのレスポンスをすべて、その同じサーバーにルーティングすることによって、元のリクエストにかわって状態情報を保持する必要があります。

図9-1 単一サーバーへのWebサービス・レスポンスのルーティング

「図9-1 単一サーバーへのWebサービス・レスポンスのルーティング」の説明

前の図に示すように、次のような処理が行われます。

1. フロントエンドSOAPルーターが、受信したHTTPリクエストをルーティングし、標準的なロード・バランシング手法でServer2に送信します。

2. Server2が、Webサービスのエンドポイント・アドレスにあるMyserviceを呼び出します。SOAPメッセージのReplyToヘッダーには、フロントエンドSOAPルーターへのポインタが含まれています。

3. MyServiceがフロントエンドSOAPルーターにレスポンスを戻します。

4. フロントエンドSOAPルーターは、レスポンスのルーティング先を決定する必要があります。Server2がレスポンスに関連する状態情報を保持しているため、フロントエンドSOAPルーターはレスポンスをServer2にルーティングします。

シナリオ2: ルーティング情報を使用した単一サーバーへのWebサービス・レスポンスのルーティング

このシナリオでは、受信したリクエストがサーバーに対してロード・バランシングされます。レスポンスには、後続のリクエストに関する元のサーバーを宛先とするルーティング情報が含まれています。

図9-2 単一サーバーへのWebサービス・リクエストのルーティング

「図9-2 単一サーバーへのWebサービス・リクエストのルーティング」の説明

前の図に示すように、次のような処理が行われます。

1. フロントエンドSOAPルーターが、受信したHTTPリクエスト(Request1)をルーティングし、標準的なロード・バランシング手法でServer2に送信します。リクエストにはルーティング情報は含まれていません。

2. Server2が、Webサービスのエンドポイント・アドレスにあるMyserviceを呼び出します。SOAPメッセージのReplyToヘッダーには、フロントエンドSOAPルーターへのポインタが含まれています。

3. MyServiceが呼出し元にレスポンスを戻します。レスポンスには、Server2を後続のすべてのリクエストのターゲットに指定するルーティング情報が含まれています。呼出し元は、レスポンスに含まれているルーティング情報を、後続のすべてのリクエスト(Request2など)に入れて渡します。

4. フロントエンドSOAPルーターが、Request2とともに渡されたルーティング情報を使用して、Request2をServer2にルーティングします。

シナリオ3: IDを使用した単一サーバーへのWebサービス・レスポンスのルーティング

このシナリオでは、受信したSOAPリクエストにIDが含まれていますが、ルーティング情報は含まれていません。同じIDを持つ後続のリクエストはすべて、同じサーバーに送られる必要があります。

図9-3 IDを使用した単一サーバーへのWebサービス・レスポンスのルーティング

「図9-3 IDを使用した単一サーバーへのWebサービス・レスポンスのルーティング」の説明

前の図に示すように、次のような処理が行われます。

1. リクエストは、ID (接続作成匿名URI)を含むWebサービス・クライアントに由来し、このIDはRequest1に関連する将来のリクエストによって共有されます。このIDのフォームはプロトコル固有のものです。

2. フロントエンドSOAPルーターがRequest1のIDを検出し、アフィニティ・ストアをチェックして、そのIDがクラスタ内の特定のサーバーに関連付けられていないかを調べます。この場合、関連付けは定義されていません。

3. フロントエンドSOAPルーターがリクエストのロード・バランシングを行い、処理のためにリクエストをServer2に送信します。

4. Server2のMyService Webサービス・インスタンスがリクエストを処理します(必要に応じてレスポンスを生成します)。この場合、シナリオ2: ルーティング情報を使用した単一サーバーへのWebサービス・レスポンスのルーティングとは異なり、ルーティング情報は伝播できません。

5. Request1で使用したのと同じIDを使用して、Request2がフロントエンドSOAPルーターに到着します。

6. フロントエンドSOAPルーターがIDを検出し、アフィニティ・ストアをチェックして、そのIDが特定のサーバーに関連付けられていないかを調べます。この場合、IDがServer2にマップされていることが判明します。

7. アフィニティ情報に基づいて、フロントエンドSOAPルーターがRequest2をServer2にルーティングします。

Webサービス・クラスタでのルーティングの仕組み

次の項では、Webサービス・クラスタでのルーティングの仕組みについて説明します。

- 送信するリクエストへのルーティング情報の追加

- 受信したリクエストのルーティング情報の検出

- クラスタ内でのリクエストのルーティング

- フロントエンドSOAPルーターでのルーティング・マップの保持

送信するリクエストへのルーティング情報の追加

Webサービス・ランタイムは、次のような場合でもメッセージのルーティングが適切に行われるよう、送信するすべてのメッセージのSOAPヘッダーにルーティング情報を追加します。

- リクエストの送信元のWebサービス・クライアントが、クラスタに属するすべてのサーバーからはアクセスできないストアを使用している場合。

- リクエストが、レスポンスの処理に使用されるメモリー内の状態情報を必要とする場合。

送信するメッセージを処理する際、Webサービス・ランタイムは次のことを実行します。

- 送信するリクエストにメッセージIDが割り当てられていない場合はメッセージIDを作成し、RelatesTo/MessageID SOAPヘッダーに次の形式で格納します。
uuid:WLSformat_version:store_name:uniqueID

説明:

- format_versionには、WebLogic Server形式のバージョン(WLS1など)を指定します。

- store_nameには、永続ストア(メッセージを送信する現在のWebサービスまたはWebサービス・クライアントによって使用されるストア)の名前を指定します。たとえば、Server1Storeです。この値は、システムで生成される名前(デフォルトの永続ストアを使用する場合)または空の文字列(永続ストアが構成されていない場合)です。

- unique_IDには、一意のメッセージIDを指定します。例:68d6fc6f85a3c1cb:-2d3b89ab8:12068ad2e60:-7febです。

- 他のWebサービス・コンポーネントが、メッセージにルーティング情報を組み込んでからメッセージを送信できるようにします。

受信したリクエストのルーティング情報の検出

SOAPルーター(インプレースまたはフロントエンド)は、受信したリクエストにルーティング情報がないかチェックします。特に、SOAPルーターはRelatesTo/MessageID SOAPヘッダーを探して永続ストアの名前を特定し、その永続ストアをホストするサーバーにメッセージを戻します。

フロントエンドSOAPルーティングを使用して正しいサーバーを判別する際にエラーが発生した場合、メッセージはクラスタ内のいずれかのサーバーに送信され、インプレースSOAPルーターが使用されます。インプレースSOAPルーターでフォルトが発生した場合、メッセージの送信元はプロトコル固有のバック・チャネルでフォルトを受信します。

注意:

ルーティング情報を含むSOAPメッセージ・ヘッダーは、平文で表す必要があります。暗号化することはできません。

クラスタ内でのリクエストのルーティング

ルーティングの決定を助けるため、SOAPルーター(インプレースまたはフロントエンド)はストアとサーバーの名前の関連付けを表す動的マッピングを使用します。この動的マップはクラスタ内の管理対象サーバーで作成されたもので、インプレースSOAPルーターはメモリー内でアクセスし、フロントエンドSOAPルーターはHTTPレスポンス・ヘッダーを介してアクセスします。HTTPレスポンス・ヘッダーは、クラスタ内のWebサービスから送信されたすべてのHTTPレスポンスに自動的に組み込まれます。

注意:

HTTPレスポンス・ヘッダーの詳細は、「フロントエンドSOAPルーターでのルーティング・マップの保持」を参照してください。

当初、動的マップは空です。初期化されるのは、クラスタ内の管理対象サーバーから最初のレスポンスを受信した後です。HTTPレスポンス・ヘッダーを含む最初のレスポンスを受信するまで、フロントエンドSOAPルーターは単にリクエストのロード・バランシングを行い、インプレースSOAPルーターはリクエストを適切なサーバーにルーティングします。

SOAPベースのルーティング情報がない場合、単純なロード・バランシング(ラウンドロビンなど)が行われている、HTTPセッション・ベースのルーティングを含むベース・ルーティングに従います。

フロントエンドSOAPルーターでのルーティング・マップの保持

「クラスタ内でのリクエストのルーティング」で述べたように、ルーティングの決定を助けるため、SOAPルーター(インプレースまたはフロントエンド)はストアとサーバーの名前の関連付けを表す動的マッピングを使用します。

この動的マップを生成するために、2つの新しいHTTPレスポンス・ヘッダーが用意されています(この後の項を参照)。これらのヘッダーは、クラスタ内のWebサービスから送信されたすべてのHTTPレスポンスに自動的に組み込まれます。

注意:

サード・パーティのフロントエンドを実装する際は、この後説明するHTTPレスポンス・ヘッダーを組み込むために、変数X-weblogic-wsee-request-storetoserver-listを任意の値に設定したHTTPリクエスト・ヘッダーを、クライアントから送信する必要があります。

X-weblogic-wsee-storetoserver-list HTTPレスポンス・ヘッダー

ストアとサーバーのマッピングの一覧は、X-weblogic-wsee-storetoserver-list HTTPレスポンス・ヘッダーに保持されます。フロントエンドSOAPルーターは、このヘッダーを使用して、実行時に参照可能なマッピングにデータを移入し、メッセージのルーティングを行います。

X-weblogic-wsee-storetoserver-list HTTPレスポンス・ヘッダーは次の形式を取ります。

storename1:host_server_spec | storename2:host_server_spec | storename3:host_server_spec

各値の説明は次のとおりです。

- storenameには、永続ストアの名前を指定します。

- host_server_specには、servername:host:port:sslportという形式で指定します。不明な場合、sslportは-1に設定されます。

X-weblogic-wsee-storetoserver-hash HTTPレスポンス・ヘッダー

ストアとサーバーのリストのハッシュ・マッピングは、X-weblogic-wsee-storetoserver-hash HTTPレスポンス・ヘッダーに指定されます。このヘッダーを使用すると、新しいマッピング・リストをリフレッシュする必要があるかどうかを判断できます。

X-weblogic-wsee-storetoserver-hash HTTPレスポンス・ヘッダーには、X-weblogic-wsee-storetoserver-list HTTPレスポンス・ヘッダーに含まれるリストのハッシュ値を表す文字列値が組み込まれます。リストの最後のエントリを追跡することで、リストのリフレッシュが必要かどうかを判断できます。

クラスタ内のWebサービスの構成

次の表に、クラスタ内のWebサービスを構成する手順をまとめます。

表9-1 クラスタ内のWebサービスを管理する手順

#

手順

説明

1

WebLogicクラスタを設定します。

「WebLogicクラスタの設定」を参照してください。

2

Webサービスの高度な機能に必要なクラスタ・ドメイン・リソースを構成します。

クラスタ拡張テンプレート・スクリプトを使用すると、必要なクラスタ・ドメイン・リソースを自動的に構成できます。もう1つの方法として、Oracle WebLogic管理コンソールまたはWLSTを使用し、リソースを構成することも可能です。「クラスタ環境におけるWebサービスの高度な機能に必要なドメイン・リソースの構成」を参照してください。

3

フロントエンドSOAPルーターを拡張してWebサービスをサポートします。

注意: この手順は、フロントエンドSOAPルーターを使用する場合のみ必要です。

Webサービス・ルーティング・サーブレットは、WebLogic HTTPクラスタ・サーブレットの機能を拡張して、クラスタ内のWebサービスのルーティングをサポートします。「フロントエンドSOAPルーターの拡張によるWebサービスのサポート」を参照してください。

4

Webサービス原子性トランザクション・メッセージのルーティングを有効にします。

「Webサービス原子性トランザクション・メッセージのルーティングの有効化」を参照してください。

5

Webサービスの接続作成メッセージのルーティングを有効にします。

「Webサービスの接続作成メッセージのルーティングの有効化」を参照してください。

6

フロントエンドSOAPルーターのIDを構成します。

クラスタ内の各WebLogic ServerインスタンスをフロントエンドSOAPルーターのアドレスおよびポートで構成する必要があります。「フロントエンドSOAPルーターのIDの構成」を参照してください。

WebLogicクラスタの設定

『Oracle WebLogic Serverクラスタの使用』のWebLogicクラスタの設定に関する項の説明に従って、WebLogicクラスタを設定します。次の点に注意してください:

- クラスタ・ドメインを構成するには、「クラスタ環境におけるWebサービスの高度な機能に必要なドメイン・リソースの構成」を参照してください。

- SOAPベースのフロントエンドSOAPルーティングを有効にするには、『Oracle WebLogic Serverクラスタの使用』のHttpClusterServletの設定に関する項の説明に従って、HTTPクラスタ・サーブレットを構成します。

クラスタ環境におけるWebサービスの高度な機能に必要なドメイン・リソースの構成

構成ウィザードを使用してドメインの作成または拡張を行う際には、WebLogic Advanced Web Services for JAX-WS拡張テンプレート(wls_webservice_jaxws.jar)を適用すると、クラスタ環境でWebサービスの高度な機能をサポートするのに必要なリソースを自動的に構成できます。この拡張テンプレートの使用は必須ではありませんが、使用すると必要なリソースの構成が格段に容易になります。あるいは、Oracle WebLogic管理コンソールまたはWLSTを使用して、これらの高度な機能に必要なリソースを構成できます。

また、テンプレートによって、ドメインの変化(サーバーの追加や削除など)に合せて、高度なWebサービスで必要なリソースを管理するために使用できるスクリプトがドメイン・ディレクトリにインストールされます。

ドメインの構成方法やリソースを管理するためのスクリプトの実行方法の詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』の高度なWeb Services機能のためのドメインの構成に関する項を参照してください。

フロントエンドSOAPルーターの拡張によるWebサービスのサポート

注意:

フロントエンドSOAPルーターを使用しない場合、この手順は不要です。

フロントエンドSOAPルーターを拡張してWebサービスをサポートするには、次の例(太字の部分)に示すRoutingHandlerClassNameパラメータを、WebLogic HTTPクラスタ・サーブレット定義の一部として指定します。

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>HttpClusterServlet</servlet-name>
<servlet-class>weblogic.servlet.proxy.HttpClusterServlet</servlet-class>
<init-param>
<param-name>WebLogicCluster</param-name>
<param-value>Server1:7001|Server2:7001</param-value>
</init-param>
<init-param>
<param-name>RoutingHandlerClassName</param-name>
<param-value>
weblogic.wsee.jaxws.cluster.proxy.SOAPRoutingHandler
</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>HttpClusterServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
. . .
</web-app>

Webサービス原子性トランザクション・メッセージのルーティングの有効化

Webサービス原子性トランザクション・メッセージの高可用性およびルーティングは、Webサービスのクラスタ環境では自動的に有効になります。ただし、WebLogic HTTPクラスタ・サーブレットがフロントエンド・サーバーとして使用されている場合は、WebLogic HTTPクラスタ・サーブレットをホストするサーバーで、次のシステム・プロパティをfalseに設定する必要があります。

weblogic.wsee.wstx.wsat.deployed=false

また、WebLogic Serverプラグインを使用するときは、WLIOTimeoutSecsパラメータ値を適切に構成する必要があります。このパラメータは、WebLogic Serverからのリクエストに対するレスポンスをプラグインが待機する時間を定義します。サーブレットによる処理の時間よりもこの値が小さい場合は、予期しない結果が生じることがあります。WLIOTimeoutSecsパラメータの詳細は、『Oracle WebLogic ServerにおけるWebサーバー・プラグインの使用』のWebサーバー・プラグインの一般的なパラメータに関する項を参照してください。

Webサービスの接続作成メッセージのルーティングの有効化

Webサービスの接続作成をサポートするには、「ファイアウォールの内側からの非同期Webサービス・クライアントの使用(接続作成)」に記載されているように、WebLogic HTTPクラスタ・サーブレットをホストしているWebLogic Server上にデフォルトの論理ストアを構成する必要があります。デフォルトの論理ストアの構成の詳細は、「論理ストアの構成」を参照してください。

フロントエンドSOAPルーターのIDの構成

クラスタ内の各WebLogic ServerインスタンスをフロントエンドSOAPルーターのアドレスおよびポートで構成する必要があります。ネットワーク・チャネルを使用すると、クラスタのフロントエンド・アドレスにアクセスするための一貫した方法を提供できます。ネットワーク・チャネルの詳細は、『Oracle WebLogic Serverサーバー環境の構成』のネットワーク・チャネルの理解に関する項を参照してください。

各サーバー・インスタンスについて、以下の手順を実行します。

1. Webサービスの呼出しに使用するプロトコル用のネットワーク・チャネルを作成します。ネットワーク・チャネルの名前は、weblogic-wsee-proxy-channel-XXXとする必要があります(XXXはプロトコルを表します)。たとえば、HTTPS用のネットワーク・チャネルを作成する場合、weblogic-wsee-proxy-channel-httpsという名前にします。
ネットワーク・チャネルの作成に関する一般情報は、Oracle WebLogic Server管理コンソール・ヘルプのカスタム・ネットワーク・チャネルの構成に関する項を参照してください。

2. 「外部リスニング・アドレス」および「外部リスニング・ポート」フィールドを、それぞれプロキシ・サーバーのアドレスおよびポートで更新して、ネットワーク・チャネルを構成します。

クラスタのルーティング・パフォーマンスのモニター

次のクラスタ・ルーティング統計をモニターすると、アプリケーションのパフォーマンスを評価できます。

- リクエストおよびレスポンスの総数。

- サーバーにルーティングされたリクエストおよびレスポンスの総数。

- ルーティングの失敗に関する情報(総数と最後の失敗を含む)。

WebLogic Server管理コンソールまたはWLSTを使用して、クラスタのルーティング・パフォーマンスをモニターできます。WebLogic Server管理コンソールを使用してクラスタのルーティング・パフォーマンスをモニターする方法については、Oracle WebLogic Server管理コンソール・ヘルプのWebサービスのモニターに関する項およびWebサービス・クライアントのモニターに関する項を参照してください。

10 Webサービス原子性トランザクションの使用

この章では、Java API for XML Web Services(JAX-WS)を使用したWebLogic Webサービスで、Webサービス原子性トランザクションを使用して他の外部トランザクション処理システムとの相互運用性を実現する方法について説明します。

この章の内容は以下のとおりです。

- Webサービス原子性トランザクションの概要

- Webサービスの高度な機能に必要なドメイン・リソースの構成

- Webサービスに対するWebサービス原子性トランザクションの有効化

- Webサービス・クライアントに対するWebサービス原子性トランザクションの有効化

- 管理コンソールを使用したWebサービス原子性トランザクションの構成

- クラスタ環境でのWebサービス原子性トランザクションの使用

- Webサービス原子性トランザクションのその他の使用例

Webサービス原子性トランザクションの概要

WebLogic Webサービスでは、次の仕様をサポートすることで、Websphere、JBoss、Microsoft .NETといった他の外部トランザクション処理システムとの相互運用性を実現しています。

- Webサービスの原子性トランザクション(WS-AtomicTransaction)バージョン1.0、1.1、および1.2: http://docs.oasis-open.org/ws-tx/wstx-wsat-1.2-spec-cs-01/wstx-wsat-1.2-spec-cs-01.html

- Webサービスのコーディネーション(WS-Coordination)バージョン1.0、1.1、および1.2: http://docs.oasis-open.org/ws-tx/wstx-wscoor-1.2-spec-cs-01/wstx-wscoor-1.2-spec-cs-01.html

これらの仕様は、一連の参加者の間で分散されたアクティビティを調整するための拡張フレームワークを定義するものです。次の図に示されているコーディネータは中心的なコンポーネントで、トランザクションの状態(調整コンテキスト)を管理し、Webサービスおよびクライアントを参加者として登録することを可能にします。

図10-1 Webサービス原子性トランザクションのフレームワーク

「図10-1 Webサービス原子性トランザクションのフレームワーク」の説明

次の表では、この図に示されているWebサービス原子性トランザクションのコンポーネントについて説明します。

表10-1 Webサービス原子性トランザクションのコンポーネント

コンポーネント

説明

コーディネータ

トランザクションの状態(調整コンテキスト)を管理し、Webサービスおよびクライアントを参加者として登録することを可能にします。

アクティブ化サービス

アプリケーションによるトランザクションのアクティブ化、およびアクティビティの調整コンテキストの作成を可能にします。作成された調整コンテキストは、トランザクション・フローとともに渡されます。

登録サービス

アプリケーションを参加者として登録することを可能にします。

アプリケーション・プロトコルX、Y

サポートされている調整プロトコル(WS-AtomicTransactionなど)。

次の図は、Webサービス原子性トランザクションのコンテキスト内で相互に作用する2つのWebLogic Serverインスタンスを示しています。わかりやすくするために、2つのWebLogic Webサービス・アプリケーションを示しています。

図10-2 WebLogic Server環境内のWebサービス原子性トランザクション

「図10-2 WebLogic Server環境内のWebサービス原子性トランザクション」の説明

以下の点に注意する必要があります。

- ローカルJTAトランザクション・マネージャを使用すると、すべてWebサービス・リクエストのコンテキスト内で、トランザクションを下位トランザクションとしてローカルなJTA環境との間でインポートおよびエクスポートできます。

- 調整コンテキストの作成と管理は、ローカルJTAトランザクション・マネージャによって行われます。

- トランザクションの整合性管理とリカバリ処理はすべて、ローカルJTAトランザクション・マネージャによって行われます。

JTAの詳細は、『Oracle WebLogic Server JTAのプログラミング』を参照してください。

次に、図10-2に示されているエンドツーエンドのWebサービス原子性トランザクションの相互作用の例について説明します。

1. アプリケーションAが、サーバーAでJTAトランザクション・マネージャを使用して、コントロールの現行スレッドに対するトランザクションを開始します。

2. アプリケーションAが、サーバーBのアプリケーションBでWebサービス・メソッドをコールします。

3. サーバーAがトランザクション情報を更新し、調整コンテキストを含むSOAPヘッダーを作成して、トランザクションおよびローカル・コーディネータを指定します。

4. サーバーBがアプリケーションBのリクエストを受信して、ヘッダーにトランザクション調整コンテキストが含まれていることを検出し、アプリケーションBがこのトランザクションの参加者としてすでに登録されているかどうかを判断します。すでに登録されていれば、そのトランザクションは再開され、登録されていない場合は、新しいトランザクションが開始されます。
アプリケーションBがインポート済トランザクションのコンテキスト内で実行されます。アプリケーションの対話に使用されるすべてのトランザクション・リソースは、このインポート済トランザクションに登録されます。

5. サーバーBが、トランザクション調整コンテキスト内で指定されている登録サービスを使用して、WS-AtomicTransactionトランザクションの参加者として自身を登録します。

6. サーバーAがトランザクションを再開します。

7. アプリケーションAが処理を再開し、トランザクションをコミットします。

Webサービスの高度な機能に必要なドメイン・リソースの構成

ドメインの作成または拡張を行う際に、Webサービス原子性トランザクションに加えて、Webサービスのその他の高度な機能を使用する予定の場合は(すぐに使用するのか、将来使用するのかを問わず)、WebLogic Advanced Web Services for JAX-WS拡張テンプレート(wls_webservice_jaxws.jar)を適用すると、Webサービスの高度な機能をサポートするのに必要なリソースを自動的に構成できます。この拡張テンプレートの使用は必須ではありませんが、使用すると必要なリソースの構成が格段に容易になります。あるいは、Oracle WebLogic管理コンソールまたはWLSTを使用して、これらの高度な機能に必要なリソースを構成できます。詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebサービスの高度な機能のためのドメインの構成に関する項を参照してください。

注意:

Webサービスのその他の高度な機能をWebサービス原子性トランザクションとともに使用する予定がない場合、この拡張テンプレートを適用する必要はなく、起動時間とメモリー・フットプリントが最小限に抑えられます。

Webサービスに対するWebサービス原子性トランザクションの有効化

Webサービスに対してWebサービス原子性トランザクションを有効にするには、次の方法があります。

- Javaから開始する場合(ボトムアップ)は、Webサービス・エンドポイントの実装クラスまたは実装メソッドに@weblogic.wsee.wstx.wsat.Transactionalアノテーションを追加します。詳細は、「JWSファイルでの@Transactionalアノテーションの使用」を参照してください。

- WSDから開始する場合(トップダウン)は、wsdlcを使用して既存のWSDLファイルからWebサービスを生成します。この場合、WSDLで通知されたWS-AtomicTransactionポリシー・アサーションが、wsdlcによって生成された新しいWebサービスのWSDLファイルに送られ、その中に組み込まれます。「WSDLから開始するWebサービス原子性トランザクションの有効化」を参照してください。

- デプロイメント時に、WebLogic Server管理コンソールを使用して、Webサービスのエンドポイント・レベルまたはメソッド・レベルでWebサービス原子性トランザクションを有効にして構成します。詳細は、「管理コンソールを使用したWebサービス原子性トランザクションの構成」を参照してください。

次の表は、Webサービス原子性トランザクションを有効にする際に設定可能な構成オプションをまとめたものです。

表10-2 Webサービス原子性トランザクションの構成オプション

属性

説明

バージョン

Webサービスおよびクライアントに対して使用されるWebサービス原子性トランザクション調整コンテキストのバージョン。クライアントの場合、アウトバウンド・メッセージに使用されるバージョンのみを指定します。指定した値は、トランザクション全体で整合性が取れている必要があります。

有効な値は、WSAT10、WSAT11、WSAT12、およびDEFAULTです。WebサービスのDEFAULT値は、3つのバージョンすべて(インバウンド・リクエストによって駆動される)であり、Webサービス・クライアントのDEFAULT値はWSAT10です。

フロー・タイプ

Webサービス原子性トランザクション調整コンテキストがトランザクション・フローとともに渡されるかどうか。有効な値は、表10-3を参照してください。

次の表は、フロー・タイプの有効な値と、Webサービスおよびクライアントでのそれらの意味をまとめたものです。この表では、@TransactionAttributeアノテーションを使用するEJB型のWebサービスに対してWebサービス原子性トランザクションを構成する際の有効な値の組合せも示しています。

表10-3 フロー・タイプの値

値

Webサービス・クライアント

Webサービス

EJB @TransactionAttributeの有効な値

NEVER

JTAトランザクションがある場合: トランザクションの調整コンテキストをエクスポートしません。

JTAトランザクションがない場合: トランザクションの調整コンテキストをエクスポートしません。

トランザクション・フローが存在する場合: トランザクションの調整コンテキストをインポートしません。CoordinationContextヘッダーにmustunderstand="true"が含まれている場合は、SOAPフォルトがスローされます。

トランザクション・フローがない場合: トランザクションの調整コンテキストをインポートしません。

NEVER、NOT_SUPPORTED、REQUIRED、REQUIRES_NEW、SUPPORTS

SUPPORTS(デフォルト)

JTAトランザクションがある場合: トランザクションの調整コンテキストをエクスポートします。

JTAトランザクションがない場合: トランザクションの調整コンテキストをエクスポートしません。

トランザクション・フローが存在する場合: トランザクション・コンテキストをインポートします。

トランザクション・フローがない場合: トランザクションの調整コンテキストをインポートしません。

REQUIRED、SUPPORTS

MANDATORY

JTAトランザクションがある場合: トランザクションの調整コンテキストをエクスポートします。

JTAトランザクションがない場合: 例外がスローされます。

トランザクション・フローが存在する場合: トランザクション・コンテキストをインポートします。

トランザクション・フローがない場合: サービス側の例外がスローされます。

MANDATORY、REQUIRED、SUPPORTS

JWSファイルでの@Transactionalアノテーションの使用

Webサービス原子性トランザクションを有効にするには、Webサービス・エンドポイントの実装クラスまたは実装メソッドに@weblogic.wsee.wstx.wsat.Transactionalアノテーションを指定します。

注意:

weblogic.jws.Transactionalもアノテーション付きのクラスまたは操作をトランザクション内で確実に実行するためのものですが、この場合のトランザクションは原子性トランザクションではありませんので、このアノテーションと混同しないでください。

以下の点に注意する必要があります。

- Webサービス・クラス・レベルで@Transactionalアノテーションを指定すると、サービス・エンドポイント・インタフェースで定義された双方向メソッドのすべてに設定が適用されます。フロー・タイプの値はメソッド・レベルでオーバーライドできますが、バージョンはトランザクション全体で一致している必要があります。

- @Onewayアノテーションも追加されているWebメソッドに対して、@Transactionalアノテーションを明示的に指定することはできません。

- Webサービス原子性トランザクションは、クライアント側の非同期プログラミング・モデルでは使用できません。

@Transactionalアノテーションを指定する際の形式は次のとおりです。

@Transactional(
version=Transactional.Version.[WSAT10|WSAT11|WSAT12|DEFAULT],
value=Transactional.TransactionFowType.[MANDATORY|SUPPORTS|NEVER]
)

バージョンおよびフロー・タイプの構成オプションの詳細は、表10-2を参照してください。

次の項では、@TransactionalアノテーションをWebサービスの実装クラス・レベルと実装メソッド・レベルで使用する例、およびEJB @TransactionAttributeアノテーションとともに使用する例を示します。

- 例: Webサービス・クラスでの@Transactionalアノテーションの使用

- 例: Webサービス・メソッドでの@Transactionalアノテーションの使用

- 例: @TransactionalアノテーションとEJB @TransactionAttributeアノテーションの併用

例: Webサービス・クラスでの@Transactionalアノテーションの使用

次の例は、@TransactionalアノテーションをWebサービス・クラスに追加する方法を示しています。関連するコードは太字で示されています。例に示すように、アクティブなJTAトランザクションがあります。

注意:

次のコードは、WebLogic Serverサンプル・サーバー付属のWebサービス原子性トランザクションの例から抜粋したものです。詳細は、「Webサービス原子性トランザクションのその他の使用例」を参照してください。

package examples.webservices.jaxws.wsat.simple.service;
. . .
import weblogic.jws.Policy;
import javax.transaction.UserTransaction;
. . .
import javax.jws.WebService;
import weblogic.wsee.wstx.wsat.Transactional;
import weblogic.wsee.wstx.wsat.Transactional.Version;
import weblogic.wsee.wstx.wsat.Transactional.TransactionFlowType;

/**
* This JWS file forms the basis of a WebLogic WS-Atomic Transaction Web Service with the
* operations: createAccount, deleteAccount, transferMonet, listAccount
*
*/

@WebService(serviceName = "WsatBankTransferService", targetNamespace = "http://tempuri.org/",
portName = "WSHttpBindingIService")
@Transactional(value=Transactional.TransactionFlowType.MANDATORY,
version=weblogic.wsee.wstx.wsat.Transactional.Version.WSAT10)
public class WsatBankTransferService {

public String createAccount(String acctNo, String amount) throws java.lang.Exception{
Context ctx = null;
UserTransaction tx = null;
try {
ctx = new InitialContext();
tx = (UserTransaction)ctx.lookup("javax.transaction.UserTransaction");
try {
DataSource dataSource = (DataSource)ctx.lookup("examples-demoXA-2");
String sql = "insert into wsat_acct_remote (acctno, amount) values (" + acctNo +
", " + amount + ")";
int insCount = dataSource.getConnection().prepareStatement(sql).executeUpdate();
if (insCount != 1)
throw new java.lang.Exception("insert fail at remote.");
return ":acctno=" + acctNo + " amount=" + amount + " creating. ";
} catch (SQLException e) {
System.out.println("**** Exception caught *****");
e.printStackTrace();
throw new SQLException("SQL Exception during createAccount() at remote.");
}
} catch (java.lang.Exception e) {
System.out.println("**** Exception caught *****");
e.printStackTrace();
throw new java.lang.Exception(e);
}
}
public String deleteAccount(String acctNo) throws java.lang.Exception{
...
}
public String transferMoney(String acctNo, String amount, String direction) throws
java.lang.Exception{
...
}
public String listAccount() throws java.lang.Exception{
...
}
}

例: Webサービス・メソッドでの@Transactionalアノテーションの使用

次の例は、@TransactionalアノテーションをWebサービス実装メソッドに追加する方法を示しています。関連するコードは太字で示されています。

package examples.webservices.jaxws.wsat.simple.service;
. . .
import weblogic.jws.Policy;
import javax.transaction.UserTransaction;
. . .
import javax.jws.WebService;
import weblogic.wsee.wstx.wsat.Transactional;
import weblogic.wsee.wstx.wsat.Transactional.Version;
import weblogic.wsee.wstx.wsat.Transactional.TransactionFlowType;

/**
* This JWS file forms the basis of a WebLogic WS-Atomic Transaction Web Service with the
* operations: createAccount, deleteAccount, transferMonet, listAccount
*
*/

@WebService(serviceName = "WsatBankTransferService", targetNamespace = "http://tempuri.org/",
portName = "WSHttpBindingIService")
public class WsatBankTransferService {

@Transactional(value=Transactional.TransactionFlowType.MANDATORY,
version=weblogic.wsee.wstx.wsat.Transactional.Version.WSAT10)
public String createAccount(String acctNo, String amount) throws java.lang.Exception{
Context ctx = null;
UserTransaction tx = null;
try {
ctx = new InitialContext();
tx = (UserTransaction)ctx.lookup("javax.transaction.UserTransaction");
try {
DataSource dataSource = (DataSource)ctx.lookup("examples-demoXA-2");
String sql = "insert into wsat_acct_remote (acctno, amount) values (" + acctNo +
", " + amount + ")";
int insCount = dataSource.getConnection().prepareStatement(sql).executeUpdate();
if (insCount != 1)
throw new java.lang.Exception("insert fail at remote.");
return ":acctno=" + acctNo + " amount=" + amount + " creating. ";
} catch (SQLException e) {
System.out.println("**** Exception caught *****");
e.printStackTrace();
throw new SQLException("SQL Exception during createAccount() at remote.");
}
} catch (java.lang.Exception e) {
System.out.println("**** Exception caught *****");
e.printStackTrace();
throw new java.lang.Exception(e);
}
}
public String deleteAccount(String acctNo) throws java.lang.Exception{
...
}
public String transferMoney(String acctNo, String amount, String direction) throws
java.lang.Exception{
...
}
public String listAccount() throws java.lang.Exception{
...
}
}

例: @TransactionalアノテーションとEJB @TransactionAttributeアノテーションの併用

次の例は、@TransactionalアノテーションとEJB @TransactionAttributeアノテーションを併用する方法を示しています。この場合、フロー・タイプの値に互換性があることが必要です(表10-3を参照)。関連するコードは太字で示されています。

package examples.webservices.jaxws.wsat.simple.service;
. . .
import weblogic.jws.Policy;
import javax.transaction.UserTransaction;
. . .
import javax.jws.WebService;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import weblogic.wsee.wstx.wsat.Transactional;
import weblogic.wsee.wstx.wsat.Transactional.Version;
import weblogic.wsee.wstx.wsat.Transactional.TransactionFlowType;

/**
* This JWS file forms the basis of a WebLogic WS-Atomic Transaction Web Service with the
* operations: createAccount, deleteAccount, transferMonet, listAccount
*
*/

@WebService(serviceName = "WsatBankTransferService", targetNamespace = "http://tempuri.org/",
portName = "WSHttpBindingIService")
@Transactional(value=Transactional.TransactionFlowType.MANDATORY,
version=weblogic.wsee.wstx.wsat.Transactional.Version.WSAT10)
@TransactionAttribute(TransactionAttributeType.REQUIRED
public class WsatBankTransferService {
. . .
}

WSDLから開始するWebサービス原子性トランザクションの有効化

Webサービス原子性トランザクションは、有効にすると、ポリシー・アサーションを使用してWSDLファイルで通知されます。

表10-4は、Webサービス原子性トランザクションのフロー・タイプとEJBトランザクション属性との一般的な組合せに対応するWS-AtomicTransaction 1.2ポリシー・アサーションをまとめたものです。他のすべての組合せではビルド時にエラーが発生します。

表10-4 Webサービス原子性トランザクションのポリシー・アサーションの値(WS-AtomicTransaction 1.2)

原子性トランザクションのフロー・タイプ

EJB @TransactionAttribute

WS-AtomicTransaction 1.2ポリシー・アサーション

MANDATORY

MANDATORY、REQUIRED、SUPPORTS

<wsat:ATAssertion/>

SUPPORTS

REQUIRED、SUPPORTS

<wsat:ATAssertion wsp:Optional="true"/>

NEVER

REQUIRED、REQUIRES_NEW、NEVER、SUPPORTS、NOT_SUPPORTED

ポリシーの通知なし

wsdlc Antタスクを使用すると、既存のWSDLファイルから一連のアーティファクトを生成し、それをまとめて、WSDLファイルに記述されたWebサービスの部分的なJava実装を提供することができます。WSDLファイルで通知されたWS-AtomicTransactionポリシー・アサーションは、wsdlcによって生成された新しいWebサービスのWSDLファイルに送られ、その中に組み込まれます。

wsdlc Antタスクでは、生成されたJWSインタフェースの部分的な(途中まで作成済の)実装を含むJWSファイルが生成されます。このファイルを変更してビジネス・コードを組み込む必要があります。ビジネス・ロジックを含むJWSファイルをコーディングしたら、jwsc Antタスクを実行して、Webサービスの完全なJava実装を生成します。wsdlc Antタスクによって生成されたJARファイル(JWSインタフェース・ファイルとデータ・バインディング・アーティファクトを含む)を指定するには、jwscのcompiledWsdl属性を使用します。この属性を指定した場合、jwsc Antタスクでは新しいWSDLファイルが生成されるかわりに、JARファイル内のWSDLファイルが使用されます。そのため、WebサービスをデプロイしてそのWSDLを参照すると、デプロイ済のWSDLは開始当初のWSDLとまったく同じように見えます(WS-AtomicTransactionポリシー・アサーションが付いています)。

wsdlcを使用してWSDLファイルからWebサービスを生成する方法の詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWSDLファイルから開始するWebLogic Webサービスの開発: 主な手順に関する項を参照してください。

Webサービス・クライアントに対するWebサービス原子性トランザクションの有効化

Webサービス・クライアントに対しては、次のいずれかの方法でWebサービス原子性トランザクションを有効にします。

- クライアントのWebサービス参照インジェクション・ポイントに@weblogic.wsee.wstx.wsat.Transactionalアノテーションを追加します。詳細は、「@Transactionalアノテーションと@WebServiceRefアノテーションの併用」を参照してください。

- Webサービスのプロキシまたはディスパッチの作成時にweblogic.wsee.wstx.wsat.TransactionalFeatureのインスタンスをパラメータとして渡します。詳細は、「TransactionalFeatureをクライアントに渡す」を参照してください。

- デプロイメント時に、WebLogic Server管理コンソールを使用して、Webサービス・クライアントのエンドポイント・レベルまたはメソッド・レベルでWebサービス原子性トランザクションを有効にして構成します。詳細は、「管理コンソールを使用したWebサービス原子性トランザクションの構成」を参照してください。

- 実行時に、原子性トランザクションに対応していないWebサービス・クライアントが。原子性トランザクションに対応しているWebサービスを呼び出すと、WSDLで示されるフロー・タイプの設定に基づいて次の処理が行われます。

- サービス側でフロー・タイプがSUPPORTSまたはNEVERに設定されている場合、呼出しはトランザクションの一部として組み込まれます。

- フロー・タイプがMANDATORYに設定されている場合、例外がスローされます。

Webサービス原子性トランザクションを有効にする際に設定可能な構成オプションについては、表10-2を参照してください。

@Transactionalアノテーションと@WebServiceRefアノテーションの併用

Webサービス原子性トランザクションを有効にするには、Webサービス・クライアントのWebサービス参照(@WebServiceRef)インジェクション・ポイントに@weblogic.wsee.wstx.wsat.Transactionalアノテーションを指定します。

@Transactionalアノテーションを指定する際の形式は次のとおりです。

@Transactional(
version=Transactional.Version.[WSAT10|WSAT11|WSAT12|DEFAULT],
value=Transactional.TransactionFlowType.[MANDATORY|SUPPORTS|NEVER]
)

バージョンおよびフロー・タイプの構成オプションの詳細は、表10-2を参照してください。

次の例は、Webサービス参照インジェクション・ポイントにアノテーションを追加する方法を示しています。関連するコードは太字で示されています。例に示すように、アクティブなJTAトランザクションは原子性トランザクションの一部になります。

注意:

次のコードは、WebLogic Serverサンプル・サーバー付属のWebサービス原子性トランザクションの例から抜粋したものです。詳細は、「Webサービス原子性トランザクションのその他の使用例」を参照してください。

package examples.webservices.jaxws.wsat.simple.client;
. . .
import javax.servlet.*;
import javax.servlet.http.*;
. . .
import java.net.URL;
import javax.xml.namespace.QName;

import javax.transaction.UserTransaction;
import javax.transaction.SystemException;

import javax.xml.ws.WebServiceRef;
import weblogic.wsee.wstx.wsat.Transactional;
*/

/**
* This example demonstrates using a WS-Atomic Transaction to create or delete an account,
* or transfer money via Web service as a single atomic transaction.
*/

public class WsatBankTransferServlet extends HttpServlet {
. . .
String url = "http://localhost:7001";
URL wsdlURL = new URL(url + "/WsatBankTransferService/WsatBankTransferService");
. . .
DataSource ds = null;
UserTransaction utx = null;

try {
ctx = new InitialContext();
utx = (UserTransaction) ctx.lookup("javax.transaction.UserTransaction");
utx.setTransactionTimeout(900);
} catch (java.lang.Exception e) {
e.printStackTrace();
}

WsatBankTransferService port = getWebService(wsdlURL);

try {
utx.begin();
if (remoteAccountNo.length() > 0) {
if (action.equals("create")) {
result = port.createAccount(remoteAccountNo, amount);
} else if (action.equals("delete")) {
result = port.deleteAccount(remoteAccountNo);
} else if (action.equals("transfer")) {
result = port.transferMoney(remoteAccountNo, amount, direction);
}
}
utx.commit();
result = "The transaction is committed " + result;
} catch (java.lang.Exception e) {
try {
e.printStackTrace();
utx.rollback();
result = "The transaction is rolled back.    " + e.getMessage();
} catch(java.lang.Exception ex) {
e.printStackTrace();
result = "Exception is caught. Check stack trace.";
}
}
request.setAttribute("result", result);
. . .
@Transactional(value = Transactional.TransactionFlowType.MANDATORY,
version = Transactional.Version.WSAT10)
@WebServiceRef(wsdlLocation =
"http://localhost:7001/WsatBankTransferService/WsatBankTransferService?WSDL", value =
examples.webservices.jaxws.wsat.simple.service.WsatBankTransferService.class)
WsatBankTransferService_Service service;
private WsatBankTransferService getWebService() {
return service.getWSHttpBindingIService();
}

public String createAccount(String acctNo, String amount) throws java.lang.Exception{
Context ctx = null;         UserTransaction tx = null;
try {
ctx = new InitialContext();
tx = (UserTransaction)ctx.lookup("javax.transaction.UserTransaction");
try {
DataSource dataSource = (DataSource)ctx.lookup("examples-dataSource-demoXAPool");
String sql = "insert into wsat_acct_local (acctno, amount) values (
" + acctNo + ", " + amount + ")";
int insCount = dataSource.getConnection().prepareStatement(sql).executeUpdate();
if (insCount != 1)
throw new java.lang.Exception("insert fail at local.");
return ":acctno=" + acctNo + " amount=" + amount + " creating.. ";
} catch (SQLException e) {
System.out.println("**** Exception caught *****");
e.printStackTrace();
throw new SQLException("SQL Exception during createAccount() at local.");
}
} catch (java.lang.Exception e) {
System.out.println("**** Exception caught *****");
e.printStackTrace();
throw new java.lang.Exception(e);
}
}

public String deleteAccount(String acctNo) throws java.lang.Exception{
. . .
}
public String transferMoney(String acctNo, String amount, String direction) throws
java.lang.Exception{
. . .
}
public String listAccount() throws java.lang.Exception{
. . .
}
}

TransactionalFeatureをクライアントに渡す

Webサービスのクライアントに対してWebサービス原子性トランザクションを有効にするには、次の例のように、Webサービスのプロキシまたはディスパッチの作成時にweblogic.wsee.wstx.wsat.TransactionalFeatureのインスタンスをパラメータとして渡します。関連するコードは太字で示されています。

注意:

次のコードは、WebLogic Serverサンプル・サーバー付属のWebサービス原子性トランザクションの例から抜粋したものです。詳細は、「Webサービス原子性トランザクションのその他の使用例」を参照してください。

package examples.webservices.jaxws.wsat.simple.client;
. . .
import javax.servlet.*;
import javax.servlet.http.*;
. . .
import java.net.URL;
import javax.xml.namespace.QName;

import javax.transaction.UserTransaction;
import javax.transaction.SystemException;

import weblogic.wsee.wstx.wsat.TransactionalFeature;
import weblogic.wsee.wstx.wsat.Transactional.Version;
import weblogic.wsee.wstx.wsat.Transactional.TransactionFlowType;
*/

/**
* This example demonstrates using a WS-Atomic Transaction to create or delete an account,
* or transfer money via Web service as a single atomic transaction.
*/

public class WsatBankTransferServlet extends HttpServlet {
. . .
String url = "http://localhost:7001";
URL wsdlURL = new URL(url + "/WsatBankTransferService/WsatBankTransferService");
. . .
DataSource ds = null;
UserTransaction utx = null;

try {
ctx = new InitialContext();
utx = (UserTransaction) ctx.lookup("javax.transaction.UserTransaction");
utx.setTransactionTimeout(900);
} catch (java.lang.Exception e) {
e.printStackTrace();
}

WsatBankTransferService port = getWebService(wsdlURL);

try {
utx.begin();
if (remoteAccountNo.length() > 0) {
if (action.equals("create")) {
result = port.createAccount(remoteAccountNo, amount);
} else if (action.equals("delete")) {
result = port.deleteAccount(remoteAccountNo);
} else if (action.equals("transfer")) {
result = port.transferMoney(remoteAccountNo, amount, direction);
}
}
utx.commit();
result = "The transaction is committed " + result;
} catch (java.lang.Exception e) {
try {
e.printStackTrace();
utx.rollback();
result = "The transaction is rolled back.    " + e.getMessage();
} catch(java.lang.Exception ex) {
e.printStackTrace();
result = "Exception is caught. Check stack trace.";
}
}
request.setAttribute("result", result);
. . .
// Passing the TransactionalFeature to the Client
private WsatBankTransferService getWebService(URL wsdlURL) {
TransactionalFeature feature = new TransactionalFeature();
feature.setFlowType(TransactionFlowType.MANDATORY);
feature.setVersion(Version.WSAT10);
WsatBankTransferService_Service service = new WsatBankTransferService_Service(wsdlURL,
new QName("http://tempuri.org/", "WsatBankTransferService"));
return service.getWSHttpBindingIService(new javax.xml.ws.soap.AddressingFeature(),
feature);
}

public String createAccount(String acctNo, String amount) throws java.lang.Exception{
Context ctx = null;         UserTransaction tx = null;
try {
ctx = new InitialContext();
tx = (UserTransaction)ctx.lookup("javax.transaction.UserTransaction");
try {
DataSource dataSource = (DataSource)ctx.lookup("examples-dataSource-demoXAPool");
String sql = "insert into wsat_acct_local (acctno, amount) values (
" + acctNo + ", " + amount + ")";
int insCount = dataSource.getConnection().prepareStatement(sql).executeUpdate();
if (insCount != 1)
throw new java.lang.Exception("insert fail at local.");
return ":acctno=" + acctNo + " amount=" + amount + " creating.. ";
} catch (SQLException e) {
System.out.println("**** Exception caught *****");
e.printStackTrace();
throw new SQLException("SQL Exception during createAccount() at local.");
}
} catch (java.lang.Exception e) {
System.out.println("**** Exception caught *****");
e.printStackTrace();
throw new java.lang.Exception(e);
}
}

public String deleteAccount(String acctNo) throws java.lang.Exception{
. . .
}
public String transferMoney(String acctNo, String amount, String direction) throws
java.lang.Exception{
. . .
}
public String listAccount() throws java.lang.Exception{
. . .
}
}

管理コンソールを使用したWebサービス原子性トランザクションの構成

次の項では、管理コンソールを使用してWebサービス原子性トランザクションを構成する方法について説明します。

- コーディネータと参加者の間で交換されるメッセージの保護

- Webサービス原子性トランザクションの有効化および構成

コーディネータと参加者の間で交換されるメッセージの保護

トランスポート・レベルのセキュリティを使用して、Webサービス原子性トランザクションのコーディネータと参加者の間で交換されるメッセージを保護するには、WebLogic Server管理コンソールで、次の表に定義されているプロパティを構成します。これらのプロパティは、ドメイン・レベルで構成します。詳しい手順は、Oracle WebLogic Server管理コンソール・ヘルプのWebサービス原子性トランザクションの構成に関する項を参照してください。

表10-5 Webサービス原子性トランザクションの保護

プロパティ

説明

Webサービス・トランザクションのトランスポート・セキュリティ・モード

コーディネータと参加者の間のメッセージ交換に双方向SSLを使用するかどうかを指定します。このプロパティは、次のいずれかの値に設定できます。

- SSLは不要: Webサービス・トランザクションのプロトコル・メッセージはすべて、HTTPチャネル経由で交換されます。

- SSLが必要: Webサービス・トランザクションのプロトコル・メッセージはすべて、HTTPSチャネル経由で交換されます。このフラグは、原子性トランザクションが有効になっているMicrosoft .NET Webサービスを起動する際に有効にする必要があります。

- クライアント証明書が必要: Webサービス・トランザクションのプロトコル・メッセージはすべてHTTPS経由で交換され、クライアント証明書が必要となります。

詳細は、Oracle WebLogic Server管理コンソール・ヘルプの双方向SSLの構成に関する項を参照してください。

Webサービス・トランザクションの発行済みトークンを有効化

発行済トークンを使用してコーディネータと参加者の間の認証を有効にするかどうかを指定するフラグ。

IssuedTokenは、コーディネータによって発行され、セキュリティ・コンテキスト・トークン(SCT)と署名用のセッション・キーで構成されます。参加者は、共有セッション・キーを使用して署名した署名を登録メッセージに入れて送信します。コーディネータは、セッション・キーを使用して署名を検証することにより、参加者を認証します。

Webサービス原子性トランザクションの有効化および構成

Webサービス原子性トランザクションを有効にしてバージョンとフロー・タイプを構成する場合、Webサービスまたはクライアントのエンドポイント・レベルまたはメソッド・レベルで構成をカスタマイズできます。詳しい手順は、Oracle WebLogic Server管理コンソール・ヘルプのWebサービス原子性トランザクションの構成に関する項を参照してください。

クラスタ環境でのWebサービス原子性トランザクションの使用

原子性トランザクションに対応しているWebサービスをクラスタ環境で使用する際の考慮事項については、第9章「クラスタ内のWebサービスの管理」を参照してください。

Webサービス原子性トランザクションのその他の使用例

Webサービス原子性トランザクションのその他の使用例については、次の項を参照してください。

- Webサービス原子性トランザクションで交換されるメッセージ・ヘッダーの署名と暗号化の方法を示す例は、『Oracle WebLogic Server WebLogic Webサービスの保護』のWebサービス原子性トランザクションの保護に関する項を参照してください。

注意:

Webサービス原子性トランザクションが有効なアプリケーションを保護するために使用できるのは、WebLogic Webサービスのセキュリティ・ポリシーのみです。Oracle Web Services Manager (WSM)ポリシーを使用して保護することはできません。

- Webサービス原子性トランザクションの詳しい例がWebLogic Serverサンプル・アプリケーションの一部として提供されています。サンプル・アプリケーションの実行と例へのアクセスの詳細は、Oracle WebLogic Serverの理解のサンプル・アプリケーションおよびサンプル・コードに関する項を参照してください。

11 Webサービスのエンドポイントのパブリッシュ

この章では、javax.xml.ws.Endpoint APIを使用して、WebサービスをWebLogic Serverインスタンスにデプロイすることなく、実行時にWebサービスのエンドポイントを作成する方法について説明します。

詳細は、http://download.oracle.com/javaee/5/api/javax/xml/ws/Endpoint.htmlを参照してください。

次の表に、Webサービスのエンドポイントをパブリッシュする手順をまとめます。

表11-1 Webサービスのエンドポイントをパブリッシュする手順

#

手順

説明

1

Webサービスのエンドポイントを作成します。

javax.xml.ws.Endpoint create()メソッドを使用してエンドポイントを作成し、エンドポイントに関連付けるインプリメンタ(Webサービスの実装)を指定し、必要に応じてバインディング・タイプを指定します。指定しない場合、バインディング・タイプのデフォルトはSOAP1.1/HTTPになります。実行時に定義したように、エンドポイントに関連付けるのは1つの実装オブジェクトと1つのjavax.xml.ws.Bindingにのみであり、これらの値は変更できません。

たとえば次の例では、CallbackWS()実装のWebサービス・エンドポイントが作成されます。

Endpoint callbackImpl = Endpoint.create(new CallbackWS());

2

受信したリクエストを受け入れるため、Webサービスのエンドポイントをパブリッシュします。

javax.xml.ws.Endpoint publish()メソッドを使用して、サーバー・コンテキストを指定するか、Webサービス・エンドポイントのアドレスとインプリメンタ(必要に応じて)を指定します。

注意: エンドポイントに関連付けられているメタデータ・ドキュメント(WSDLまたはXMLスキーマ)を更新したい場合は、エンドポイントをパブリッシュする前に更新する必要があります。

たとえば次の例では、ステップ1でサーバー・コンテキストを使用して作成したWebサービス・エンドポイントがパブリッシュされます。

Object sc
context.getMessageContext().get(MessageContext.SERVLET_CONTEXT);
callbackImpl.publish(sc);

3

Webサービスのエンドポイントを停止して、処理完了後に追加のリクエストが受け入れられないようにします。

javax.xml.ws.Endpointのstop()メソッドを使用してエンドポイントを停止し、受信したリクエストの受け入れを停止します。いったん停止したエンドポイントをパブリッシュし直すことはできません。

例:

callbackImpl.stop()

コールバック・サンプルのコンテキスト内でWebサービスのエンドポイントをパブリッシュする例については、「コールバック・クライアントWebサービスのプログラミングのガイドライン」を参照してください。

上の表に示した手順に加え、javax.xml.ws.Endpoint APIのメソッドを使用して以下を定義することもできます。

- エンドポイントに関連付けるエンドポイント・メタデータ・ドキュメント(WSDLまたはXMLスキーマ)。メタデータは、Webサービス・エンドポイントをパブリッシュする前に定義する必要があります。

- エンドポイント・プロパティ。

- アプリケーションに対する受信したリクエストのディスパッチに使用するjava.util.concurrent.Executor。(http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Executor.htmlを参照)。

詳細は、javax.xml.ws.EndpointのJavadoc(http://download.oracle.com/javaee/5/api/javax/xml/ws/Endpoint.html)を参照してください。

12 コールバックの使用

この章では、Java API for XML Web Services(JAX-WS)を使用したWebLogic Webサービスで、コールバックを使用してクライアントにイベントを通知する方法について説明します。

この章の内容は以下のとおりです。

- コールバックの概要

- コールバック実装のサンプル

- コールバックのプログラミング手順

- ターゲットWebサービスのプログラミングのガイドライン

- コールバック・クライアントWebサービスのプログラミングのガイドライン

- コールバックWebサービスのプログラミングのガイドライン

コールバックの概要

コールバックとは、クライアントとサービスの間の規約の1つです。サービスはコールバックを使用することで、クライアントに追加のデータを照会することを目的として、サービス・メソッドの呼出しの間にクライアント提供のエンドポイントで操作を呼び出すことができます。これにより、クライアントが動作を注入したり、クライアントに進行状況を通知したりすることが可能になります。サービスは、コールバックのポート・タイプを定義するWSDLを使用してコールバックの要件を公開します。一方クライアントは、WS-Addressingを使用して、コールバック・エンドポイントのアドレスをサービスに通知します。

コールバック実装のサンプル

この節で説明するコールバック実装のサンプルは、以下の3つのJavaファイルから構成されています。

- コールバックWebサービスを実装するJWSファイル: コールバックWebサービスには、コールバック・メソッドが定義されています。この実装からターゲットWebサービスに情報が返送され、最終的にクライアントWebサービスに返送されます。
この項で示すサンプルでは、コールバックWebサービスの名前をCallbackServiceとしています。このWebサービスには、単一のコールバック・メソッド、callback()が定義されています。

- ターゲットWebサービスを実装するJWSファイル: ターゲットWebサービスには、コールバックWebサービスに定義されたメソッドを呼び出す1つ以上の標準操作が含まれます。ターゲットWebサービス操作の呼出し元であるクライアントWebサービスには、ターゲットWebサービスからメッセージが返送されます。
例では、このWebサービスの名前がTargetServiceになっており、単一の標準メソッドtargetOperation()が定義されています。

- クライアントWebサービスを実装するJWSファイル: クライアントWebサービスは、ターゲットWebサービスの操作を呼び出します。多くの場合、このWebサービスには、コールバック・メソッドを介してターゲットWebサービスからコールバック・メッセージを受け取ったときにクライアントが実行すべき動作を指定する1つ以上のメソッドが含まれます。
サンプルでは、このWebサービスの名前をCallerServiceとしています。call()は、TargetServiceを標準の方法で呼び出すメソッドです。

次の図に、コールバック実装のサンプルでのメッセージの流れを示します。

図12-1 コールバック実装のサンプル

「図12-1 コールバック実装のサンプル」の説明

1. あるWebLogic Serverインスタンスで実行されているCallerService Webサービスのcall()メソッドが、TargetServiceのtargetOperation()メソッドを明示的に呼び出し、CallbackServiceにWebサービスのエンドポイントを渡します。通常、TargetServiceサービスは、別のWebLogic Serverインスタンスで実行されています。

2. TargetService.targetOperation()メソッドの実装が、CallbackServiceのcallback()メソッドを明示的に呼び出します。このメソッドは、呼び出されると、CallerServiceから渡されたWebサービス・エンドポイントを使用して、コールバック・サービスを実装します。

3. CallbackService.callback()メソッドが、TargetService Webサービスに情報を返送します。

4. 最終的に、TargetService.targetOperation()メソッドが情報をCallerServiceサービスに返送し、コールバック・シーケンスが完了します。

コールバックのプログラミング手順

この項の手順では、コールバックを実装するために必要な3つのJWSファイル(ターゲットWebサービス、クライアントWebサービス、コールバックWebサービス)をプログラミングおよびコンパイルする方法について説明します。この手順では、これらのJWSファイルをゼロから作成する方法を示しています。既存のJWSファイルを更新する場合は、この手順をガイドとして利用してください。

Antベースの開発環境を設定済であり、かつjwsc Antタスクを実行してWebサービスをデプロイするためのターゲットを追加できる、作業用のbuild.xmlファイルがあることが前提となっています。詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』を参照してください。

表12-1 コールバックのプログラミング手順

#

手順

説明

1

ターゲットWebサービスを実装する、新しいJWSファイルを作成するか、既存のJWSファイルを更新します。

使い慣れたIDEまたはテキスト・エディタを使用します。「ターゲットWebサービスのプログラミングのガイドライン」を参照してください。

注意: ターゲットWebサービスを実装するJWSファイルは、コールバックWebサービスの1つ以上のコールバック・メソッドを呼び出します。ただし、コールバックWebサービスをプログラミングする手順については後ほど説明します。したがって、これらの3つのJWSファイルは、この手順に従って順番にプログラミングするのではなく、すべてを同時にプログラミングすることをお薦めします。手順をこの順番に説明しているのは、あくまで各手順を理解しやすくするためです。

2

build.xmlファイルを更新して、ターゲットJWSファイルをWebサービスにコンパイルするjwsc Antタスクの呼出しを含めます。

「ターゲットWebサービスのbuild.xmlファイルの更新」を参照してください。

3

Antターゲットを実行して、ターゲットWebサービスをビルドします。

例:

prompt> ant build-target

4

ターゲットWebサービスを通常どおりデプロイします。

『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebLogic Webサービスのデプロイとアンデプロイに関する項を参照してください。

5

クライアントWebサービスを実装する、新しいJWSファイルを作成するか、既存のJWSファイルを更新します。

クライアントWebサービスは、ターゲットWebサービスをホストするものとは別のWebLogic Serverインスタンスにデプロイされていることが前提となっています。「コールバック・クライアントWebサービスのプログラミングのガイドライン」を参照してください。

6

コールバックWebサービスを実装するJWSファイルを作成します。

「コールバックWebサービスのプログラミングのガイドライン」を参照してください。

7

クライアントWebサービスをビルドするbuild.xmlファイルを更新します。

クライアントWebサービスをビルドするjwsc Antタスクでは、CallbackWS.javaもコンパイルされます。また、そのクラス・ファイルは、Fileset Antタスク要素によってWARファイルに格納されます。例:

<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

Antターゲットを実行して、クライアントおよびコールバックWebサービスをビルドします。

例:

prompt> ant build-caller

9

クライアントWebサービスを通常どおりデプロイします。

『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebLogic Webサービスのデプロイとアンデプロイに関する項を参照してください。

ターゲットWebサービスのプログラミングのガイドライン

次のサンプルでは、ターゲットWebサービスを実装する簡単なJWSファイルを示します。太字で示されたJavaコードに対応するコーディングのガイドラインについては、サンプルの後の説明を参照してください。

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";
}
}

ターゲットWebサービスを実装するJWSファイルをプログラミングする際には、次のガイドラインに従います。ガイドラインのコード・スニペットは、前述のサンプルでは太字で示されています。

- コールバック・サービスのエンドポイントを渡すために必要なパッケージをインポートし、CallbackServiceスタブ実装にアクセスします。

import javax.xml.ws.wsaddressing.W3CEndpointReference;
import examples.webservices.callback.callbackservice.*;

- このスタブ実装を使用してCallbackService実装のインスタンスを作成し、呼出し側アプリケーション(CallerService)から渡されたCallbackServiceサービスのエンドポイントを渡すことでポートを取得します。

CallbackService aservice = new CallbackService();
CallbackPortType aport =
aservice.getPort(callback, CallbackPortType.class);

- インスタンス化したポートを使用して、CallbackServiceのコールバック操作を呼び出します。

String result = aport.callback(s);

- 結果をCallerServiceサービスに返します。

return result + " processed by target";

コールバック・クライアントWebサービスのプログラミングのガイドライン

次のサンプルでは、「ターゲットWebサービスのプログラミングのガイドライン」で説明したターゲットWebサービスを呼び出すクライアントWebサービス用の簡単なJWSファイルを示します。太字で示されたJavaコードに対応するコーディングのガイドラインについては、サンプルの後の説明を参照してください。

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

ターゲットWebサービスを呼び出すJWSファイルをプログラミングする際には、次のガイドラインに従います。ガイドラインのコード・スニペットは、前述のサンプルでは太字で示されています。

- サーブレット・コンテキストにアクセスするために必要なパッケージをインポートし、WebサービスのエンドポイントをパブリッシュしてTargetServiceスタブ実装にアクセスします。

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.*;

- WebServiceContextおよびMessageContextを使用してサーブレット・コンテキストを取得します。サーブレット・コンテキストは、後ほどWebサービスのエンドポイントをパブリッシュする際に使用します。

@Resource
private WebServiceContext context;
.
.
.
Object sc
context.getMessageContext().get(MessageContext.SERVLET_CONTEXT);

WebServiceContextおよびMessageContextを使用した実行時情報へのアクセスの詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebサービスの実行時情報へのアクセスに関する項を参照してください。

- CallbackService実装に渡すWebサービスのエンドポイントを作成し、受信したリクエストを受け入れるためにエンドポイントをパブリッシュします。

Endpoint callbackImpl = Endpoint.create(new CallbackWS());
callbackImpl.publish(sc);

Webサービスのパブリッシュの詳細は、第11章「Webサービスのエンドポイントのパブリッシュ」を参照してください。

- TargetServiceスタブ実装のインスタンスにアクセスし、インスタンス化したポートを使用してTargetServiceのtargetOperation操作を呼び出します。CallbackServiceサービスのエンドポイントは、javax.xml.ws.wsaddressing.W3CEndpointReferenceデータ型として渡します。

@WebServiceRef()
private TargetService target;
.
.
.
TargetPortType tPort = target.getTargetPort();
String result = tPort.targetOperation(s,
callbackImpl.getEndpointReference(W3CEndpointReference.class));

- エンドポイントのパブリッシュを停止します。

callbackImpl.stop();

コールバックWebサービスのプログラミングのガイドライン

次のサンプルでは、コールバックWebサービスを実装する簡単なJWSファイルを示します。callback操作は太字で示されています。

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();
}
}

ターゲットWebサービスのbuild.xmlファイルの更新

build.xmlファイルを更新して、コールバックWebサービスを呼び出すターゲットWebサービスを生成するには、次のサンプルのようにtaskdefsおよびbuild-targetターゲットを追加します。詳細は、サンプルの後の説明を参照してください。

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

jwsc Antタスクの完全なクラス名を定義するには、taskdef Antタスクを使用します。クライアントWebサービスをコンパイルするjwsc Antタスクを次のように更新します。

- デプロイ済CallbackService WebサービスのServiceインタフェース・スタブを生成およびコンパイルするため、<jws>要素の<clientgen>子要素を追加します。jwsc Antタスクでは、これらのスタブが生成されたWARファイルに自動的にパッケージ化されるため、即座にクライアントWebサービスからアクセスできるようになります。このようにするのは、生成されたクラスの1つをTartgetImpl JWSファイルでインポートして使用するためです。

- WARファイル内のCallbackServiceサービスのWSDLを含めるための<zip>要素を追加して、他のWebサービスがURL http://${wls.hostname}:${wls.port}/callback/wsdls/Callback.wsdlからWSDLにアクセスできるようにします。

jwscの詳細は、『Oracle WebLogic Server JAX-RPC Webサービス・スタート・ガイド』のjwsc Weblogic WebサービスAntタスクの実行に関する項を参照してください。

13 バイナリ・データ転送の最適化

この章では、Java API for XML Web Services(JAX-WS)を使用したWebLogic Webサービスの転送を最適化するために、SOAPメッセージを添付ファイルとして送信する方法について説明します。

この章の内容は以下のとおりです。

- MTOM/XOPを使用したバイナリ・データ転送の最適化

- SOAP添付ファイルのストリーミング

- swaRefを使用した添付ファイル付きSOAPメッセージの送信

MTOM/XOPを使用したバイナリ・データ転送の最適化

SOAP MTOM/XOP (Message Transmission Optimization Mechanism/XML-binary Optimized Packaging)では、SOAPメッセージ内のxs:base64Binary型またはxs:hexBinary型のXMLデータの転送を最適化する方法が定義されています。トランスポート・プロトコルがHTTPの場合、Multipurpose Internet Mail Extension(MIME)添付ファイルを使用して、送信側と受信側の両方に対して同時にSOAPメッセージ内のXMLデータへの直接アクセスを許可する間にデータを伝達します。このとき、base64BinaryまたはhexBinaryデータのマーシャリングにMIMEアーティファクトが使用されていたことを意識する必要はありません。

バイナリ・データ最適化プロセスの手順は次のとおりです。

1. バイナリ・データのエンコード

2. SOAPエンベロープからのバイナリ・データの削除

3. バイナリ・データの圧縮

4. MIMEパッケージへのバイナリ・データの添付

5. SOAPエンベロープ内のMIMEパッケージへの参照の追加

MTOM/XOPのサポートは、JWSアノテーションの使用によって、JAX-WSでは標準となっています。MTOM仕様では、MTOMが有効化されている場合に、base64binaryまたはhexBinaryデータの送信時にWebサービスのランタイムでXOPバイナリ最適化を使用することは必須ではありません。むしろ、この仕様では、ランタイムがこれを選択して行うようになっています。これは場合によっては、直接SOAPメッセージ内にバイナリ・データを送信するほうが、より効率的であるとランタイムで判断されることがあるためです。一例としては、トランスポートされるデータ量が少なく、単にデータをそのままインライン処理するよりも多くのリソースが、会話およびトランスポートのオーバーヘッドにより消費されてしまう場合が挙げられます。

デフォルトでbase64Binary XMLデータ型にマップされるJavaタイプは、javax.activation.DataHandler、java.awt.Imageとjavax.xml.transform.Sourceです。base64BinaryまたはhexBinary型の要素は、デフォルトでbyte[]にマップされます。

次の表に、MTOM/XOPを使用してbase64BinaryまたはhexBinary型の添付ファイルを送信する手順をまとめます。

表13-1 MTOM/XOPを使用してバイナリ・データを送信する手順

#

手順

説明

1

MTOM添付ファイルとして使用する予定のデータ型のアノテーションを追加します。(オプション)

使用するプログラミング・モデルに応じ、JavaクラスまたはWSDLにアノテーションを追加して、バイナリ・データの送信に使用するコンテンツ・タイプを定義できます。この手順はオプションです。XMLバイナリ型は、デフォルトではJava byte[]にマップされます。詳細については、「データ型のアノテーションの追加」を参照してください。

2

WebサービスでMTOMを有効にします。

「WebサービスでMTOMの有効化」を参照してください。

3

WebサービスのクライアントでMTOMを有効にします。

「クライアントでMTOMの有効化」を参照してください。

4

添付ファイルのしきい値の設定

xs:binary64データをインラインまたは添付ファイルとして送信する場合に指定する添付ファイルのしきい値を設定します。「添付ファイルのしきい値の設定」を参照してください。

詳細は、次を参照してください。

- MTOMの仕様(http://www.w3.org/TR/soap12-mtom)

- XOPの仕様(http://www.w3.org/TR/xop10)

データ型のアノテーションの追加

使用するプログラミング・モデルに応じ、JavaクラスまたはWSDLにアノテーションを追加して、バイナリ・データの送信に使用するMIMEコンテンツ・タイプを定義できます。この手順はオプションです。

次の表に、MIMEコンテンツ・タイプとJavaタイプのマッピングを定義します。型によっては、デフォルトのマッピングが存在します。デフォルトのマッピングが存在しないMIMEコンテンツ・タイプは、DataHandlerにマップされます。

表13-2 MIMEコンテンツ・タイプとJava型のマッピング

MIMEコンテンツ・タイプ

Java型

image/gif

java.awt.Image

image/jpeg

java.awt.Image

text/plain

java.lang.String

text/xml or application/xml

javax.xml.transform.Source

*/*

javax.activation.DataHandler

以下の節では、データ型のアノテーションを追加する方法について説明します。Javaから始める方法と、WSDLから始める方法があります。

- データ型のアノテーションを追加する: Javaから始める場合

- データ型のアノテーションを追加する: WSDLから始める場合

データ型のアノテーションを追加する: Javaから始める場合

バイナリ・データの送信に使用するコンテンツ・タイプの定義をJavaから始める場合は、バイナリ・データを保持するフィールドに@XmlMimeTypeアノテーションを追加します。

バイナリ・データを保持するフィールドは、DataHandler型にする必要があります。

次のサンプルに、バイナリ・データを保持するJavaクラス内のフィールドにアノテーションを追加する方法を示します。

@WebMethod
@Oneway
public void dataUpload(
@XmlMimeType("application/octet-stream") DataHandler data)
{
}

データ型のアノテーションを追加する: WSDLから始める場合

バイナリ・データの送信に使用するコンテンツ・タイプの定義をWSDLから始める場合は、以下のいずれかの属性を使用して、xs:base64Binaryまたはxs:hexBinary型のWSDL要素にアノテーションを追加します。

- xmime:contentType - この要素のコンテンツ・タイプを定義します。

- xmime:expectedContentType - バイナリ・データとして容認するメディア・タイプの範囲を定義します。

次のサンプルでは、base64binary型のimage要素を、java.awt.Image Javaタイプにマップされるimage/gif MIMEタイプにマップしています。

<element name="image" type="base64Binary"
xmime:expectedContentTypes="image/gif"
xmlns:xmime="http://www.w3.org/2005/05/xmlmime"/>

WebサービスでMTOMの有効化

次の項で説明しているように、アノテーションまたはWS-Policyファイルを使用してWebサービスでMTOMを有効にすることができます。

- アノテーションを使用してWebサービスでMTOMの有効化

- WS-Policyファイルを使用してWebサービスでMTOMの有効化

アノテーションを使用してWebサービスでMTOMの有効化

WebサービスでMTOMを有効にするには、次のサンプルのようにサービス・エンドポイント実装クラスに@java.xml.ws.soap.MTOMアノテーションを指定します。関連するコードは太字で示されています。

package examples.webservices.mtom;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.xml.ws.soap.MTOM;

@MTOM
@WebService(name="MtomPortType",
serviceName="MtomService",
targetNamespace="http://example.org")
public class MTOMImpl {
@WebMethod
public String echoBinaryAsString(byte[] bytes) {
return new String(bytes);

}
}

WS-Policyファイルを使用してWebサービスでMTOMの有効化

前の項で説明したように、@MTOMアノテーションに加えて、WebLogic JAX-WS WebサービスでのMTOM/XOPのサポートはあらかじめパッケージ化されたWS-PolicyファイルMtom.xmlを使用して実装されます。WS-Policyファイルは、http://www.w3.org/TR/ws-policyで記述されるWS-Policy仕様に準拠しています。この仕様では、WEBサービスのポリシー(この場合は、バイナリ・データ送信のためのMTOM/XOPの使用)を記述および通信する汎用モデルおよびXML構文を提供しています。WebサービスWSDLのtypesセクションへの、あらかじめパッケージ化されたMtom.xml WS-Policyファイルのインストールは、次のようになります(参考のためにのみ掲載しています。このファイルを変更することはできません)。

<wsp:Policy wsu:Id="myService_policy">
<wsp:ExactlyOne>
<wsp:All>
<wsoma:OptimizedMimeSerialization
xmlns:wsoma="http://schemas.xmlsoap.org/ws/2004/09/policy/optimizedmimeserialization" />
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>

コンパイルされたJWSファイルをWebLogic Serverにデプロイすると、MTOM WS-Policyファイルを参照する次のスニペットが動的WSDLに自動的に含まれます。このスニペットでは、WebサービスがMTOM/XOPを使用することを示しています。

<wsdl:binding name="BasicHttpBinding_IMtomTest"
type="i0:IMtomTest">
<wsp:PolicyReference URI="#myService_policy" />
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />

JWSファイルで@Policyメタデータ・アノテーションを指定することによって、開発時にWebサービスとMtom.xml WS-Policyファイルを関連付けることができます。動的WSDLに、必須であるMtom.xmlファイルへの参照が確実に含まれるよう、必ずattachToWsdl=true属性も指定します。下記の例を参照してください。

デプロイメント時にWebサービスとMtom.xml WS-Policyファイルを関連付けるには、デプロイメント直前にtypesセクションにポリシーを追加し、WSDLを修正します。

また、管理コンソールを使用して実行時にファイルを追加できます。詳細は、『Oracle WebLogic Server管理コンソール・ヘルプ』のWS-PolicyファイルとWebサービスとの関連付けに関する項を参照してください。この節では、JWSアノテーションの使用方法について説明します。

次の簡単なJWSファイルの例では、JWSファイルで@weblogic.jws.Policyアノテーションを使用して、あらかじめパッケージ化されたMtom.xmlファイルをWebサービスに適用することを指定する方法を示します(該当するコードは太字で示してあります)。

package examples.webservices.mtom;
import javax.jws.WebMethod;
import javax.jws.WebService;
import weblogic.jws.Policy;
@WebService(name="MtomPortType",
serviceName="MtomService",
targetNamespace="http://example.org")
@Policy(uri="policy:Mtom.xml", attachToWsdl=true)
public class MtomImpl {
@WebMethod
public String echoBinaryAsString(byte[] bytes) {
return new String(bytes);
}

クライアントでMTOMの有効化

WebサービスのクライアントでMTOMを有効にするには、次のサンプルのように、Webサービスのプロキシまたはディスパッチの作成時にパラメータとしてjavax.xml.ws.soap.MTOMFeatureのインスタンスを渡します。関連するコードは太字で示されています。

package examples.webservices.mtom.client;

import javax.xml.ws.soap.MTOMFeature;

public class Main {
public static void main(String[] args) {
String FOO = "FOO";
MtomService service = new MtomService()
MtomPortType port = service.getMtomPortTypePort(new MTOMFeature());
String result = null;
result = port.echoBinaryAsString(FOO.getBytes());
System.out.println( "Got result: " + result );
}
}

添付ファイルのしきい値の設定

xs:binary64データをインラインまたは添付ファイルとして送信する場合に指定する添付ファイルのしきい値を設定できます。デフォルトの添付ファイルのしきい値は0バイトです。すべてのxs:binary64データは添付ファイルとして送信されます。

添付ファイルのしきい値を設定する方法は以下のとおりです。

- Webサービスで、threshold属性を@java.xml.ws.soap.MTOMアノテーションに渡します。例:

@MTOM(threshold=3072)

- Webサービスのクライアントで、しきい値をjavax.xml.ws.soap.MTOMFeatureに渡します。例:

MtomPortType port = service.getMtomPortTypePort(new MTOMFeature(3072));

上のどちらの例でも、メッセージが3KB以上だと添付ファイルとして送信されます。それ以外の場合、コンテンツはSOAPメッセージ本文の一部としてインラインで送信されます。

SOAP添付ファイルのストリーミング

注意:

com.sun.xml.ws.developer.StreamingDataHandler APIは、JAX-WS RIの拡張としてサポートされています。このAPIはWebLogicソフトウェアの一部としては提供されないため、変更される可能性があります。

MTOMと、javax.activation.DataHandlerおよびcom.sun.xml.ws.developer.StreamingDataHandler APIを使用すると、添付ファイルを含む着信SOAPメッセージを読み取る際に、デフォルト動作としてメッセージ全体をメモリーに読み込むかわりに、WebサービスでストリーミングAPIを使用することを指定できます。この機能を使用すると、SOAPメッセージが非常に大きいWebサービスのパフォーマンスを向上させることができます。

注意:

ストリームMTOMはメッセージの暗号化と組み合せて使用できません。

以降の節では、クライアント側およびサーバー側でSOAP添付ファイルのストリーミングを使用する方法について説明します。

クライアント側のサンプル

次のサンプルでは、クライアント側でSOAP添付ファイルのストリーミングを使用する方法を示します。

package examples.webservices.mtomstreaming.client;

import java.util.Map;
import java.io.InputStream;
import javax.xml.ws.soap.MTOMFeature;
import javax.activation.DataHandler;
import javax.xml.ws.BindingProvider;
import com.sun.xml.ws.developer.JAXWSProperties;
import com.sun.xml.ws.developer.StreamingDataHandler;

public class Main {
public static void main(String[] args) {
MtomStreamingService service = new MtomStreamingService();
MTOMFeature feature = new MTOMFeature();
MtomStreamingPortType port = service.getMtomStreamingPortTypePort(
feature);
Map<String, Object> ctxt=((BindingProvider)port).getRequestContext();
ctxt.put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192);
DataHandler dh = new DataHandler(new
FileDataSource("/tmp/example.jar"));
port.fileUpload("/tmp/tmp.jar",dh);

DataHandler dhn = port.fileDownload("/tmp/tmp.jar");
StreamingDataHandler sdh = {StreamingDataHandler)dh;
try{
File file = new File("/tmp/tmp.jar");
sdh.moveTo(file);
sdh.close();
}
catch(Exception e){
e.printStackTrace();
}
}
}

このサンプルでは以下を行っています。

- WebサービスのクライアントでMTOMを有効にし、Webサービスのプロキシまたはディスパッチの作成時にパラメータとしてjavax.xml.ws.soap.MTOMFeatureのインスタンスを渡します。

- MTOMストリーミング・クライアントでのHTTPチャンクを有効にすることで、HTTPストリーミングのサポートを構成します。

Map<String, Object> ctxt = ((BindingProvider)port).getRequestContext();
ctxt.put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192);

- port.fileUploadメソッドを呼び出します。

- DataHandlerをStreamingDataHandlerにキャストし、StreamingDataHandler.readOnce()メソッドを使用して添付ファイルを読み込みます。

サーバー側のサンプル

次のサンプルでは、サーバー側でSOAP添付ファイルのストリーミングを使用する方法を示します。

package examples.webservices.mtomstreaming;

import java.io.File;
import java.jws.Oneway;
import javax.jws.WebMethod;
import java.io.InputStream;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlMimeType;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.soap.MTOM;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import com.sun.xml.ws.developer.StreamingAttachment;
import com.sun.xml.ws.developer.StreamingDataHandler;

@StreamingAttachment(parseEagerly=true, memoryThreshold=40000L)
@MTOM
@WebService(name="MtomStreaming",
serviceName="MtomStreamingService",
targetNamespace="http://example.org",
wsdlLocation="StreamingImplService.wsdl")
@Oneway
@WebMethod
public class StreamingImpl {

// Use @XmlMimeType to map to DataHandler on the client side
public void fileUpload(String fileName,
@XmlMimeType("application/octet-stream")
DataHandler data) {
try {
StreamingDataHandler dh = (StreamingDataHandler) data;
File file = new File(fileName);
dh.moveTo(file);
dh.close();
} catch (Exception e) {
throw new WebServiceException(e);
}

@XmlMimeType("application/octet-stream")
@WebMethod
public DataHandler fileDownload(String filename)
{
return  new DataHandler(new FileDataSource(filename));
}
}

このサンプルでは以下を行っています。

- ストリームSOAP添付ファイルを構成するには、@StreamingAttachementアノテーションを使用します。詳細については、「SOAP添付ファイルのストリーミングの構成」を参照してください。

- DataHandlerをマップするため、@XmlMimeTypeアノテーションを以下のように使用します。

- WSDLから始める場合は、生成されたSEIでxmime:expectedContentTypes="application/octet-stream"をDataHandlerにマップするために使用します。

- Javaから始める場合は、生成されたWSDLで適切なスキーマ・タイプを生成するために使用します。

- DataHandlerをStreamingDataHandlerにキャストし、StreamingDataHandler.moveTo(File)メソッドを使用して添付されたコンテンツをファイルに格納します。

SOAP添付ファイルのストリーミングの構成

クライアント側およびサーバー側でのSOAP添付ファイルのストリーミングは、以下を指定することで構成できます。

- 大きな添付ファイルを格納するディレクトリ。

- ストリーミング添付ファイルを徹底的に解析するかどうか。

- メモリーに格納できる添付ファイルの最大サイズ(バイト)。添付ファイルのサイズが指定したバイト数を超える場合はファイルに書き込まれます。

サーバーでSOAP添付ファイルのストリーミングの構成

注意:

com.sun.xml.ws.developer.StreamingAttachment APIは、JDK 6.0の拡張としてサポートされています。このAPIはJDK 6.0キットの一部としては提供されないため、変更される可能性があります。

サーバーでSOAP添付ファイルのストリーミングを構成するには、エンドポイント実装で@StreamingAttachmentアノテーションを追加します。次のサンプルでは、ストリーミング添付ファイルを徹底的に解析すること(完全な添付ファイルの読取りまたは書込み)を指定し、メモリーのしきい値を4MBに設定しています。4MB以下の添付ファイルはメモリーに格納されます。

...
import com.sun.xml.ws.developer.StreamingAttachment;
import javax.jws.WebService;

@StreamingAttachment(parseEagerly=true, memoryThreshold=4000000L)
@WebService(name="HelloWorldPortType", serviceName="HelloWorldService")
public class StreamingImpl {
}

クライアントでのSOAP添付ファイルのストリーミングの構成

注意:

com.sun.xml.ws.developer.StreamingAttachmentFeature APIは、JDK 6.0の拡張としてサポートされています。このAPIはJDK 6.0キットの一部としては提供されないため、変更される可能性があります。

クライアントでSOAP添付ファイルのストリーミングを構成するには、StreamingAttachmentFeatureオブジェクトを作成し、PortTypeスタブ実装の作成時に引数として渡します。次のサンプルでは、大きなファイルを格納するディレクトリを/tmpに設定し、ストリーミング添付ファイルを徹底的に解析することを指定した上で、メモリーのしきい値を4MBに設定しています。4MB以下の添付ファイルはメモリーに格納されます。

...
import com.sun.xml.ws.developer.StreamingAttachmentFeature;
...
MTOMFeature mtom = new MTOMFeature();
StreamingAttachmentFeature stf = new StreamingAttachmentFeature("/tmp", true, 4000000L);
MtomStreamingService service = new MtomStreamingService();
MtomStreamingPortType port = service.getMtomStreamingPortTypePort(
mtom, stf);
...

swaRefを使用した添付ファイル付きSOAPメッセージの送信

また、表13-3に定義されている仕様は、swaRef XML添付型を使用して添付ファイル付きSOAPメッセージを送信するメカニズムを定義しています。

表13-3 添付ファイル付きSOAPメッセージの送信をサポートする仕様

仕様

説明

SOAP With Attachments (SwA)

添付ファイルをSOAPメッセージでパッケージ化するためのMIME multipart/related構造を定義します。詳細は、http://www.w3.org/TR/SOAP-attachmentsを参照してください。

WS-I Attachments Profile

添付ファイルへの参照をコンテンツID(CID)のURLとして表すためにWSDL記述で使用可能なswaRefスキーマ・タイプを定義します。WS-Iは、swaRef型を定義するパブリック・スキーマを公開しています。このパブリック・スキーマの定義はhttp://ws-i.org/profiles/basic/1.1/xsd/swaref.xsdのXSDを参照してください。

JAXBは、swaRefスキーマ・タイプをjavax.activation.DataHandlerにマップします。

詳細は、http://www.ws-i.org/Profiles/AttachmentsProfile-1.0-2004-08-24.htmlを参照してください。

次の例では、WSDLファイルでswaRefを使用して、claimFormリクエスト・メッセージおよびレスポンス・メッセージが添付ファイルとして渡されるように指定する方法を示します。

例13-1 swaRefデータ型を使用したWSDLファイルの例

<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions name="SOAPBuilders-mime-cr-test"
xmlns:types="http://example.org/mime/data"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://example.org/mime"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
targetNamespace="http://example.org/mime">

<wsdl:types>
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.org/mime/data"
xmlns:xmime="http://www.w3.org/2005/05/xmlmime"
elementFormDefault="qualified"
xmlns:ref="http://ws-i.org/profiles/basic/1.1/xsd">
<import namespace="http://ws-i.org/profiles/basic/1.1/xsd"
schemaLocation="WS-ISwA.xsd"/>
. . .
<complexType name="claimFormTypeRequest">
<sequence>
<element name="request" type="ref:swaRef"/>
</sequence>
</complexType>
<complexType name="claimFormTypeResponse">
<sequence>
<element name="response" type="ref:swaRef"/>
</sequence>
</complexType>

<element name="claimFormRequest"  type="types:claimFormTypeRequest"/>
<element name="claimFormResponse" type="types:claimFormTypeResponse"/>
</schema>

</wsdl:types>
. . .
<wsdl:message name="claimFormIn">
<wsdl:part name="data" element="types:claimFormRequest"/>
</wsdl:message>

<wsdl:message name="claimFormOut">
<wsdl:part name="data" element="types:claimFormResponse"/>
</wsdl:message>
. . .
<wsdl:portType name="Hello">
. . .
<wsdl:operation name="claimForm">
<wsdl:input message="tns:claimFormIn"/>
<wsdl:output message="tns:claimFormOut"/>
</wsdl:operation>
</wsdl:portType>
. . .
</wsdl:definitions>

例13-1のWSDLの例で指定したように、swaRef型としてタグ付けされたXMLコンテンツはMIME添付ファイルとして送信され、例13-2に示すように、SOAP本体内の要素でこの添付ファイルへの参照が保持されます。

例13-2 MIME添付ファイル付きSOAPメッセージの例

Content-Type: Multipart/Related; start-info="text/xml"; type="application/xop+xml";
boundary="----=_Part_4_32542424.1118953563492"Content-Length: 1193SOAPAction: ""
------=_Part_5_32550604.1118953563502Content-Type: application/xop+xml; type="text/xml"; charset=utf-8
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<request xmlns="http://example.org/mtom/data">
cid:b0a597fd-5ef7-4f0c-9d85-6666239f1d25@example.jaxws.sun.com
</request>
</soapenv:Body>
</soapenv:Envelope>
------=_Part_5_32550604.1118953563502
Content-Type: application/xmlContent-ID:
<b0a597fd-5ef7-4f0c-9d85-6666239f1d25@example.jaxws.sun.com>
<?xml
version="1.0" encoding="UTF-8"?><application xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocaption="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/application_1_4.xsd" version="1.4">
<display-name>Simple example of application</display-name>
<description>Simple example</description>
<module>
<ejb>ejb1.jar</ejb>
</module>
<module>
<ejb>ejb2.jar</ejb>
</module>
<module>
<web> <web-uri>web.war</web-uri> <context-root>web</context-root></web>
</module></application>

例13-3では、claimForm操作を定義するWebサービスのサンプルを示します。WSDLに定義されているように、リクエスト・メッセージおよびレスポンス・メッセージは、MIME添付ファイルとして送信されます。

例13-3 Webサービスの例

package mime.server;

import javax.jws.WebService;
import javax.xml.ws.Holder;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.activation.DataHandler;
import java.awt.*;
import java.io.ByteArrayInputStream;

@WebService (endpointInterface = "mime.server.Hello")
public class HelloImpl {
...
public ClaimFormTypeResponse claimForm(ClaimFormTypeRequest data){
ClaimFormTypeResponse resp = new ClaimFormTypeResponse();
resp.setResponse(data.getRequest());
return resp;
}
...
}

例13-4では、claimForm操作を呼び出すWebサービス・クライアントのサンプルを示します。添付ファイルとして転送されるクライアント・リクエスト・データは、DataHandlerデータ型にマップされます。

例13-4 MIME添付ファイルを使用したWebサービス・クライアントの例

package mime.client;

import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.Source;
import javax.activation.DataHandler;
import java.io.ByteArrayInputStream;
import java.awt.*;

public class MimeApp {
public static void main (String[] args){
try {
Object port = new HelloService().getHelloPort ();
testSwaref ((Hello)port);
} catch (Exception ex) {
ex.printStackTrace ();
}
}

private static void testSwaref (Hello port) throws Exception{
DataHandler claimForm = new DataHandler (new StreamSource(
new ByteArrayInputStream(sampleXML.getBytes())), "text/xml");
ClaimFormTypeRequest req = new ClaimFormTypeRequest();
req.setRequest(claimForm);
ClaimFormTypeResponse resp = port.claimForm (req);
DataHandler out = resp.getResponse();
...
}

private static final String sampleXML = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \n" +
"<NMEAstd>\n" +
"<DevIdSentenceId>$GPRMC</DevIdSentenceId>\n" +
"<Time>212949</Time>\n" +
"<Navigation>A</Navigation>\n" +
"<NorthOrSouth>4915.61N</NorthOrSouth>\n" +
"<WestOrEast>12310.55W</WestOrEast>\n" +
"<SpeedOnGround>000.0</SpeedOnGround>\n" +
"<Course>360.0</Course>\n" +
"<Date>030904</Date>\n" +
"<MagneticVariation>020.3</MagneticVariation>\n" +
"<MagneticPoleEastOrWest>E</MagneticPoleEastOrWest>\n" +
"<ChecksumInHex>*6B</ChecksumInHex>\n" +
"</NMEAstd>";
}

14 動的プロキシ・クライアントの開発

この章では、静的プロキシ・クライアントと動的プロキシ・クライアントの違いを明確にするとともに、Java API for XML Web Services(JAX-WS)を使用したWebLogic Webサービスの動的プロキシ・クライアントを開発する手順について説明します。

この章の内容は以下のとおりです。

- 静的プロキシ・クライアントと動的プロキシ・クライアントの概要

- 動的プロキシ・クライアントの開発手順

- WSDLの場所を指定する際のその他の考慮事項

静的プロキシ・クライアントと動的プロキシ・クライアントの概要

表14-1は、静的プロキシ・クライアントと動的プロキシ・クライアントの違いを示しています。

表14-1 静的プロキシ・クライアントと動的プロキシ・クライアントの比較

プロキシ・クライアントのタイプ

説明

静的プロキシ・クライアント

開発時にWebサービス・クライアントをコンパイルしてバインドします。これにより、Webサービス・クライアント・プロキシの静的スタブが生成されます。生成される静的スタブ・クライアントのソース・コードは、特定のサービス実装に依存します。そのため、このオプションには柔軟性がほとんどありません。

静的プロキシ・クライアントの例は、次を参照してください。

- 『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebサービス・クライアントの呼出しに関する項

- 第3章「Webサービス・クライアントを開発する手順」

動的プロキシ・クライアント

開発時には何もコンパイルしません。実行時にアプリケーションがWSDLの取得および解析を行い、動的に呼出しを構成します。動的プロキシ・クライアントを使用すると、実行時にclientgenを使用することなく、サービス・エンドポイント・インタフェース(SEI)に基づいて、Webサービス・クライアントからWebサービスを動的に呼び出すことが可能になります。このオプションは、特定のサービス実装に依存しないため柔軟性は増しますが、パフォーマンス・ヒットも大きくなります。

動的プロキシ・クライアントの開発手順は、「動的プロキシ・クライアントの開発手順」を参照してください。

動的プロキシ・クライアントの開発手順

動的プロキシ・クライアントを作成する手順を次の表に示します。詳細は、javax.xml.ws.ServiceのJavadoc(http://download.oracle.com/javaee/5/api/javax/xml/ws/Service.html)を参照してください。

表14-2 動的プロキシ・クライアントの作成手順

#

手順

説明

1

javax.xml.ws.Serviceインスタンスの作成

Service.createメソッドを使用してServiceインスタンスを作成します。

サービス名と、必要に応じてWSDLドキュメントの格納場所を渡す必要があります。メソッドの詳細は次のとおりです。

public static Service create (QName serviceName) throws javax.xml.ws.WebServiceException {}
public static Service create (URL wsdlDocumentLocation, QName serviceName) throws javax.xml.ws.WebServiceException {}

例:

URL wsdlLocation = new URL("http://example.org/my.wsdl");
QName serviceName = new QName("http://example.org/sample", "MyService");
Service s = Service.create(wsdlLocation, serviceName);

使用方法に関するその他の情報は、「WSDLの場所を指定する際のその他の考慮事項」を参照してください。

2

プロキシ・スタブを作成します。

Service.getPortメソッドを使用してプロキシ・スタブを作成します。このスタブを使用すると、ターゲット・サービス・エンドポイント上の操作を呼び出すことができます。

サービス・エンドポイント・インタフェース(SEI)と、必要に応じてWSDLサービス記述内のポートの名前を渡す必要があります。メソッドの詳細は次のとおりです。

public <T> T getPort(QName portName, Class<T> serviceEndpointInterface) throws javax.xml.ws.WebServiceException {}
public <T> T getPort(Class<T> serviceEndpointInterface) throws javax.xml.ws.WebServiceException {}

例:

MyPort port = s.getPort(MyPort.class);

WSDLの場所を指定する際のその他の考慮事項

HTTPSを使用してWSDLからWebサービスを取得する際に、WebLogic Server SSL証明書のホスト名定義がピアHTTPSサーバーのホスト名と同一ではない場合、または次のいずれかではない場合には、ホスト名検証エラーが発生して処理が失敗します。

- localhost

- 127.0.0.1

- localhostのホスト名

- localhostのIPアドレス

ホスト名検証エラーは次のとおりです。

EchoService service = new EchoService(https-wsdl, webservice-qName);
:
:
javax.xml.ws.WebServiceException: javax.net.ssl.SSLKeyException:
Security:090504 Certificate chain received from host.company.com - 10.167.194.63
failed hostname verification check. Certificate contained {....} but
check expected host.company.com

推奨される回避策は、サービスを作成する際にHTTPSではなくHTTPを使用してWSDLからWebサービスを取得すること、そしてサービスの作成後に独自のホスト名検証コードを使用してホスト名を検証することです。

EchoService service = Service.create(http_wsdl, qname);
//get Port
EchoPort port = service.getPort(...);
//set self-defined hostname verifier
((BindingProvider) port).getRequestContext().put(
com.sun.xml.ws.developer.JAXWSProperties.HOSTNAME_VERIFIER,
new  MyHostNameVerifier());
/*
*/

必要に応じて、バインディング・プロバイダ・プロパティを設定してホスト名検証を無視することもできます。

((BindingProvider) port).getRequestContext().put(
BindingProviderProperties.HOSTNAME_VERIFICATION_PROPERTY,
"true");

ただし、HTTPSを使用してWSDLからWebサービスを取得する必要がある場合は、いくつかの回避策が考えられます。

- WebLogic Server HTTPS接続を使用している場合は、ホスト名検証を無効にします。そのためには、ホスト名検証を無視するグローバル・システム・プロパティを設定します。

weblogic.security.SSL.ignoreHostnameVerification=true

接続がJDK接続またはその他の非WebLogic Server接続の場合、このシステム・プロパティはサービスの作成には使用できません。

- WSDLからWebサービスを取得する前に接続に対する独自のホスト名検証を設定し、その後HTTPSを使用してWSDLからWebサービスを取得します。

//set self-defined hostname verifier
URL url = new URL(https_wsdl);
HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();
connection.setHostnameVerifier(new MyHostNameVerifier());

//then initiate the service
EchoService service = Service.create(https_wsdl, qname);

//get port and set self-defined hostname verifier to binding provider
...

回避策として独自のホスト名検証を設定する場合のホスト名検証の例を次に示します。

public class MyHostnameVerifier implements HostnameVerifier {
public boolean verify(String hostname, SSLSession session) {
if (hostname.equals("the host you want"))
return true;
else
return false;
}
}

15 XMLカタログの使用

この章では、Java API for XML Web Services(JAX-WS)を使用したWebLogic WebサービスでXMLカタログを使用する方法について説明します。

この章の内容は以下のとおりです。

- XMLカタログの概要

- XMLカタログの定義と参照

- クライアント・ランタイムでのXMLカタログの無効化

- XMLリソースのローカル・コピーの取得

XMLカタログの概要

アプリケーションでXMLカタログを使用すると、WSDLやXSDなどのインポート済XMLリソースを、Webサービスの記述の一部ではないソースから参照できます。この方法によるXMLリソースのリダイレクトは、パフォーマンスを向上させるため、またはローカル環境においてアプリケーションを常に正しく実行できるようにするために必要になる場合があります。

たとえば、クライアントの生成時にはWSDLにアクセスできても、クライアントの実行時にはWSDLにアクセスできなくなることがあります。ネットワーク経由で参照できるリソースではなく、ローカルのリソースやアプリケーションにバンドルされているリソースを参照する必要が生じることもあります。XMLカタログ・ファイルを使用すると、Webサービスが実行時に使用するWSDLの場所を指定できます。

次の表に、WebLogic Server AntタスクでXMLカタログがどのようにサポートされるかをまとめます。

表15-1 WebLogic Server AntタスクでのXMLカタログのサポート

Antタスク

説明

clientgen

XMLカタログは、以下のいずれかの方法で定義および参照できます。

- catalog属性を使用して、外部XMLカタログ・ファイルの名前を指定します。詳細については、「外部XMLカタログの定義」を参照してください。

- <xmlcatalog>子要素を使用して埋め込んだXMLカタログ・ファイルを参照します。詳細については、「XMLカタログを埋め込み」を参照してください。

クライアントをビルドするためにclientgen Antタスク(clientgenタスクが埋み込まれている場合はjwsc Antタスク)を実行すると、jax-ws-catalog.xmlファイルが生成されてクライアントの実行時環境にコピーされます。jax-ws-catalog.xmlファイルには、外部XMLカタログ・ファイルに定義されているXMLカタログや、build.xmlファイルに埋み込まれているXMLカタログが格納されています。このファイルは、参照されるXMLターゲットとともに、エンタープライズ・アプリケーションのMETA-INFフォルダ、またはWebアプリケーションのWEB-INFフォルダにコピーされます。

注意: XMLリソースの内容は、このプロセスの間は影響を受けません。

jax-ws-catalog.xmlファイルが、クライアントの実行時環境にコピーされないようにすることもできます。詳細については、「クライアント・ランタイムでのXMLカタログの無効化」を参照してください。

wsdlc

XMLカタログは、以下のいずれかの方法で定義および参照できます。

- catalog属性を使用して、外部XMLカタログ・ファイルの名前を指定します。詳細については、「外部XMLカタログの定義」を参照してください。

- <xmlcatalog>子要素を使用して埋め込んだXMLカタログ・ファイルを参照します。詳細については、「XMLカタログを埋め込み」を参照してください。

wsdlc Antタスクを実行すると、コンパイル済みのWSDL JARファイルまたは展開されたディレクトリにXMLリソースがコピーされます。

wsdlget

XMLカタログは、以下のいずれかの方法で定義および参照できます。

- catalog属性を使用して、外部XMLカタログ・ファイルの名前を指定します。詳細については、「外部XMLカタログの定義」を参照してください。

- <xmlcatalog>子要素を使用して埋め込んだXMLカタログ・ファイルを参照します。詳細については、「XMLカタログを埋め込み」を参照してください。

wsdlget Antタスクを実行すると、WSDLとインポートされたリソースが指定のディレクトリにダウンロードされます。

注意: XMLリソースの内容は、XMLカタログに定義されているリソースの参照のため更新されます。

以降の節では、以下の内容について説明します。

- リダイレクトしたいXMLリソースを指定するため、XMLカタログを定義して参照する方法。「XMLカタログの定義と参照」を参照してください。

- クライアント・ランタイムでXMLカタログを無効化する方法。「クライアント・ランタイムでのXMLカタログの無効化」を参照してください。

- wsdlgetを使用して、WSDLとそのインポート済みXMLリソースのローカル・コピーを取得する方法。これらのファイルは、アプリケーションにパッケージ化し、XMLカタログ内から参照できます。「XMLリソースのローカル・コピーの取得」を参照してください。

XMLカタログの詳細は、(http://www.oasis-open.org/committees/download.php/14809/xml-catalogs.html)のOasis XMLカタログ仕様を参照してください。

XMLカタログの定義と参照

XMLカタログは、以下のいずれかの方法で作成し、build.xmlファイル内のclientgenまたはwsdlc Antタスクから参照できます。

- 外部XMLカタログの定義 - 外部XMLカタログ・ファイルを定義し、そのファイルをbuild.xmlファイル内のclientgenまたはwsdlc Antタスクからcatalogs属性を使用して参照します。詳細については、「外部XMLカタログの定義」を参照してください。

- XMLカタログの埋め込み - <xmlcatalog>要素を使用してXMLカタログを直接build.xmlファイルに埋め込み、<xmlcatalog>子要素を使用してbuild.xmlファイル内のclientgenまたはwsdlc Antタスクから参照します。詳細については、「XMLカタログを埋め込み」を参照してください。

競合が発生した場合は、外部XMLカタログに定義されているエントリよりも、埋め込みXMLカタログに定義されているエントリが優先されます。

注意:

wsdlget Antタスクを使用すると、XMLリソースのローカル・コピーを取得できます。詳細については、「クライアント・ランタイムでのXMLカタログの無効化」を参照してください。

外部XMLカタログの定義

外部XMLカタログを定義するには、次の手順に従います。

1. リダイレクトしたいXMLリソースを定義した外部XMLカタログを作成します。「外部XMLカタログ・ファイルの作成」を参照してください。

2. 作成したXMLカタログ・ファイルを、catalogs属性を使用してbuild.xmlファイル内のclientgenまたはwsdlc Antタスクから参照します。「外部XMLカタログ・ファイルの参照」を参照してください。

以降の節では、これらの各手順について詳しく説明します。

外部XMLカタログ・ファイルの作成

<catalog>要素はXMLカタログのルート要素で、XMLカタログ・エントリのコンテナとして機能します。XMLカタログ・エンティティを指定するには、たとえばsystem要素やpublic要素を使用します。

次に、XMLカタログ・ファイルのサンプルを示します。

<catalog xmln="urn:oasis:names:tc:entity:xmlns:xml:catalog"
prefer="system">
<system systemId="http://foo.org/hello?wsdl"
uri="HelloService.wsdl" />
<public publicId="ISO 8879:1986//ENTITIES Added Latin 1//EN"
uri="wsdl/myApp/myApp.wsdl"/>
</catalog>

このサンプルで注目すべき点は以下のとおりです。

- <catalog>ルート要素によってXMLカタログのネームスペースが定義され、システムの一致が優先されることを指定するためprefer属性がsystemに設定されています。

- <system>要素により、URI参照がシステムIDに関連付けられています。

- <public>要素により、URI参照がパブリックIDに関連付けられています。

XMLカタログ・ファイル構文の詳細は、(http://www.oasis-open.org/committees/download.php/14809/xml-catalogs.html)のOasis XMLカタログ仕様を参照してください。

外部XMLカタログ・ファイルの参照

作成したXMLカタログ・ファイルをbuild.xmlファイル内のclientgenまたはwsdlc Antタスクから参照するには、catalogs属性を使用します。

次のサンプルでは、clientgenを使用してXMLカタログを参照する方法を示します。関連するコード行は太字で示されています。

<target name="clientgen">
<clientgen
type="JAXWS"
wsdl="${wsdl}"
destDir="${clientclasses.dir}"
packageName="xmlcatalog.jaxws.clientgen.client"
catalog="wsdlcatalog.xml"/>
</clientgen>
</target>

XMLカタログを埋め込み

XMLカタログを埋め込むには、次の手順に従います。

1. build.xmlファイル内に埋め込みXMLカタログを作成します。「埋め込みXMLカタログの作成」を参照してください。

2. 作成した埋め込みXMLカタログを、xmlcatalog子要素を使用してclientgenまたはwsdlc Antタスクから参照します。「埋め込みXMLカタログの参照」を参照してください。

以降の節では、これらの各手順について詳しく説明します。

注意:

競合が発生した場合は、外部XMLカタログに定義されているエントリよりも、埋め込みXMLカタログに定義されているエントリが優先されます。

埋め込みXMLカタログの作成

<xmlcatalog>要素を使用すると、XMLカタログを直接build.xmlファイルに埋め込むことができます。次のサンプルに、build.xmlファイルに埋め込まれたXMLカタログを示します。

<xmlcatalog id="wsimportcatalog">
<entity publicid="http://helloservice.org/types/HelloTypes.xsd"
location="${basedir}/HelloTypes.xsd"/>
</xmlcatalog>

XMLカタログ・ファイル構文の詳細は、(http://www.oasis-open.org/committees/download.php/14809/xml-catalogs.html)のOasis XMLカタログ仕様を参照してください。

埋め込みXMLカタログの参照

clientgenまたはwsdlc Antタスクの<xmlcatalog>子要素を使用すると、埋め込みXMLカタログを参照できます。<xmlcatalog>要素を指定するには、次の構文を使用します。

<xmlcatalog refid="id"/>

<Xmlcatalog>子要素によって参照されるidは、埋め込みXMLカタログのIDと一致している必要があります。

次のサンプルでは、clientgenを使用して埋め込みXMLカタログを参照する方法を示します。関連するコード行は太字で示されています。

<target name="clientgen">
<clientgen
type="JAXWS"
wsdl="${wsdl}"
destDir="${clientclasses.dir}"
packageName="xmlcatalog.jaxws.clientgen.client"
catalog="wsdlcatalog.xml"/>
<xmlcatalog refid="wsimportcatalog"/>
</clientgen>
</target>
<xmlcatalog id="wsimportcatalog">
<entity publicid="http://helloservice.org/types/HelloTypes.xsd"
location="${basedir}/HelloTypes.xsd"/>
</xmlcatalog>

クライアント・ランタイムでのXMLカタログの無効化

「XMLカタログの定義と参照」に従ってbuild.xmlファイル内でXMLカタログを定義して参照する場合、clientgen Antタスクを実行してクライアントをビルドすると、デフォルトではjax-ws-catalog.xmlファイルが生成されてクライアント実行時環境にコピーされます。jax-ws-catalog.xmlファイルには、外部XMLカタログ・ファイルに定義されているXMLカタログや、build.xmlファイルに埋み込まれているXMLカタログが格納されています。このファイルは、参照されるXMLターゲットとともに、エンタープライズ・アプリケーションのMETA-INFフォルダ、またはWebアプリケーションのWEB-INFフォルダにコピーされます。

クライアント実行時環境でのXMLカタログ・アーティファクトの生成は、clientgenのgenRuntimeCatalog属性をfalseに設定することで無効にできます。例:

<clientgen
type="JAXWS"
wsdl="${wsdl}"
destDir="${clientclasses.dir}"
packageName="xmlcatalog.jaxws.clientgen.client"
catalog="wsdlcatalog.xml"
genRuntimeCatalog="false"/>

この場合、jax-ws-catalog.xmlファイルは実行時環境にはコピーされません。

genRuntimeCatalog属性をfalseに設定した状態でクライアントを生成した場合、後からクライアント・ランタイムでXMLカタログを有効にするには、jax-ws-catalog.xmlファイルを手動で作成し、エンタープライズ・アプリケーションのMETA-INFフォルダまたはWebアプリケーションのWEB-INFフォルダにコピーする必要があります。jax-ws-catalog.xmlファイルには、外部XMLカタログ・ファイルに定義されているすべてのエントリ、またはbuild.xmlファイルに埋め込まれているすべてのエントリが含まれていることを確認します。

XMLリソースのローカル・コピーの取得

wsdlget Antタスクを使用すると、WSDLやXSDファイルなどのXMLリソースのローカル・コピーを取得できます。その後は、「XMLカタログの定義と参照」で説明したとおり、XMLカタログを使用してXMLリソースのローカル・コピーを参照できます。

次に示すAnt build.xmlファイルの抜粋に、wsdlget Antタスクを使用してWSDLとそのXMLリソースをダウンロードする方法を示します。XMLリソースは、Antタスクの実行ディレクトリ内のwsdlフォルダに保存されます。

<target name="wsdlget"
<wsdlget
wsdl="http://host/service?wsdl"
destDir="./wsdl/"
/>
</target>

16 SOAPフォルトを使用した例外処理

この章では、Java API for XML Web Services (JAX-WS)を使用したWebLogic Webサービスで、メッセージの処理中に発生する例外をSimple Object Access Protocol (SOAP)フォルトを使用して処理する方法について説明します。

この章の内容は以下のとおりです。

- SOAPフォルトを使用した例外処理の概要

- SOAPフォルト要素のコンテンツ

- モデル化されたフォルトの使用

- モデル化されていないフォルトの使用

- 例外処理プロセスのカスタマイズ

- SOAPフォルトからのスタック・トレースの無効化

- その他の例外

SOAPフォルトを使用した例外処理の概要

Webサービス・リクエストの処理中にエラーが発生した場合、クライアント、すなわちリクエストの送信者にそのエラーの内容を通知する必要があります。クライアントは、各種言語を使用して様々なプラットフォーム上に作成できるため、エラーを通知するには、プラットフォームに依存しない標準のメカニズムが必要です。

SOAP仕様(http://www.w3.org/TR/soap/で入手可能)では、SOAPフォルトを使用して、SOAPメッセージにエラーを記述するためのプラットフォームに依存しない標準の方法を定義しています。一般に、SOAPフォルトはアプリケーション例外に類似しています。SOAPフォルトは、ビジネス・ロジック・エラーや予期せぬ状況を報告するために受信側によって生成されます。

JAX-WSでは、Java WebサービスによってスローされるJava例外(java.lang.Exception)がSOAPフォルトにマップされ、フォルトの理由を通知するためにクライアントに返されます。SOAPフォルトのタイプは、次のいずれかになります。

- モデル化: Webサービスのデプロイ時に、Javaコードのビジネス・ロジックから明示的にスローされ、WSDLファイルのwsdl:fault定義にマップされる例外にマップされます。この場合、SOAPフォルトは事前に定義されています。

- 非モデル化: WSDLにビジネス・ロジック・フォルトが定義されていない場合に、実行時に生成される例外(java.lang.RuntimeExceptionなど)にマップされます。この場合、Java例外は汎用的なSOAPフォルト例外であるjavax.xml.ws.soap.SOAPFaultExceptionとして表されます。

フォルトは、リクエスト/レスポンス・メッセージングが使用中の場合にのみ送信者に返されます。Webサービス操作が一方向として構成されている場合、SOAPフォルトは送信者には返されませんが、後続の処理のために格納されます。

図16-1に示すように、JAX-WSはSOAPプロトコル・バインディングでSOAPフォルト処理を行います。SOAPバインディングは、例外をSOAPフォルト・メッセージにマップします。

図16-1 SOAPフォルト処理の仕組み

「図16-1 SOAPフォルト処理の仕組み」の説明

SOAPフォルト要素のコンテンツ

SOAPメッセージでエラーおよびステータス情報を送信するには、SOAP <Fault>要素を使用します。<Fault>要素は本体要素の子要素です。SOAPメッセージの本体には<Fault>要素を1つだけ含めることができます。

次の項では、SOAP 1.2および1.1のSOAP <Fault>要素のコンテンツを定義します。

- SOAP 1.2 <Fault>要素のコンテンツ

- SOAP 1.1 <Fault>要素のコンテンツ

SOAP 1.2 <Fault>要素のコンテンツ

SOAP 1.2の<Fault>要素には、表16-1に定義されているサブ要素が含まれます。

表16-1 SOAP 1.2 <Fault>要素のサブ要素

要素のサブ要素" title="SOAP 1.2 <Fault>要素のサブ要素" width="100%">

サブ要素

説明

必須/省略可能

env:Code

フォルト・エラー・コードに関する情報。env:Code要素は次の2つのサブ要素で構成されます。

- env:Value

- env: Subcode

これらのサブ要素は次のように定義されています。

必須

env:Value

フォルトに関する詳細情報を示すコード値。SOAP仕様で事前に定義されている一連のコード値は次のとおりです。

- VersionMismatch: SOAPエンベロープ要素に無効な名前空間が定義されています。SOAPエンベロープは、http://schemas.xmlsoap.org/soap/envelopeの名前空間に準拠する必要があります。

- MustUnderstand: SOAPヘッダー・エントリが処理側で認識できません。

- Sender: メッセージのフォーマットが正しくないか、情報が欠落しています。

- Receiver: サーバーの問題によりメッセージを処理できません。

- DataEncodingUnknown: 受信したメッセージには、認識できないエンコーディング・スタイルの値が使用されています。SOAPヘッダー・ブロックおよびSOAP本体の子要素に対してエンコーディング・スタイルを定義できます。このエンコーディング・スタイルはWebサービスのサーバーで認識される必要があります。

必須

env:Subcode

フォルトに関する詳細情報を示すサブコード値。このサブ要素は、再帰的構造をとることができます。

省略可能

env:Reason

フォルトに関する判読可能な記述。

<env:Reason>要素には、1つ以上の<Text>要素が含まれており、それぞれの要素にはフォルトに関する情報が異なる言語で格納されます。

必須

env:Node

フォルトを発生させたアクター(SOAPノード)に関する情報。

省略可能

env:Role

フォルトが発生したときにアクターが実行していたロール。

省略可能

env:Detail

アプリケーション固有の情報(スローされた例外など)。

省略可能

次の例では、SOAP 1.2のフォルト・メッセージを示します。

例16-1 SOAP 1.2のフォルト・メッセージの例

<?xml version="1.0"?>
<env:Envelope xmlns:env=http://www.w3.org/2003/05/soap-envelope>
<env:Body>
<env:Fault>
<env:Code>
<env:Value>env:Sender</env:Value>
<env:Subcode>
<env:Value>rpc:BadArguments</env:Value>
</env:Subcode>
</env:Code>
<env:Reason>
<env:Text xml:lang=en-US>Processing error<env:Text>
</env:Reason>
<env:Detail>
<e:myFaultDetails
xmlns:e=http://travelcompany.example.org/faults>
<e:message>Name does not match card number</e:message>
<e:errorcode>999</e:errorcode>
</e:myFaultDetails>
</env:Detail>
</env:Fault>
</env:Body>
</env:Envelope>

SOAP 1.1 <Fault>要素のコンテンツ

SOAP 1.1の<Fault>要素には、表16-2に定義されているサブ要素が含まれます。

表16-2 SOAP 1.1 <Fault>要素のサブ要素

要素のサブ要素" title="SOAP 1.1 <Fault>要素のサブ要素" width="100%">

サブ要素

説明

faultcode

フォルトに関する詳細情報を示す標準コード。SOAP仕様で事前に定義されている一連のコード値は次のとおりです。この一連のフォルト・コード値は、アプリケーションで拡張できます。

事前定義済のフォルト・コード値は次のとおりです。

- VersionMismatch: SOAPエンベロープ要素に無効な名前空間が定義されています。SOAPエンベロープは、http://schemas.xmlsoap.org/soap/envelopeの名前空間に準拠する必要があります。

- MustUnderstand: SOAPヘッダー・エントリが処理側で認識できません。

- Client: メッセージのフォーマットが正しくないか、情報が欠落しています。

- Server: サーバーの問題によりメッセージを処理できません。

faultstring

フォルトに関する判読可能な記述。

faultactor

フォルトを発生させたアクター(SOAPノード)に関連付けられているURI。RPCスタイルのメッセージングでは、アクターはWebサービスのURIです。

detail

アプリケーション固有の情報(スローされた例外など)。この要素は、XML構造またはプレーン・テキストにすることができます。

次の例では、SOAP 1.1のフォルト・メッセージを示します。

例16-2 SOAP 1.1のフォルト・メッセージの例

<?xml version="1.0"?>
<soap:Envelope
xmlns:soap='http://schemas.xmlsoap.org/soap/envelope'>
<soap:Body>
<soap:Fault>
<faultcode>soap:VersionMismatch</faultcode>
<faultstring, xml:lang='en">
Message was not SOAP 1.1 compliant
</faultstring>
<faultactor>
http://sample.org.ocm/jws/authnticator
</faultactor>
</soap:Fault>
</soap:Body>
</soap:Envelope>

モデル化されたフォルトの使用

前述したように、モデル化されたフォルトは、Javaコードのビジネス・ロジックから明示的にスローされる例外にマップされます。この場合、その例外は、Webサービスのデプロイ時にWSDLファイルのwsdl:fault定義にマップされます。

次の項では、モデル化されたフォルトの使用に関する詳細を説明します。

- カスタム例外の作成と使用

- モデル化されたフォルトのWSDLファイルにおけるマッピングの仕組み

- SOAPメッセージによるフォルト通知の仕組み

- Webサービス・クライアントの作成

カスタム例外の作成と使用

モデル化されたフォルトを使用するには、カスタムのJava例外を作成して、Webサービス内からスローする必要があります。

例16-3では、Webサービスからスローされるカスタム例外の簡単な例を示します。この例外の名前はMissingNameで、入力引数が空の場合にスローされます。

例16-3 カスタム例外を使用したWebサービス

package examples;
import javax.jws.WebService;

@WebService(name="HelloWorld", serviceName="HelloWorldService")
public class HelloWorld {
public String sayHelloWorld(String message) throws MissingName {
System.out.println("Say Hello World: " + message);
if (message == null || message.isEmpty()) {
throw new MissingName();
}
return "Here is the message: '" + message + "'";
}
}

例16-4に、例外のクラスMissingName.javaを示します。

例16-4 カスタム例外クラス(MissingName)

package examples;
import java.lang.Exception;

public class MissingName extends Exception {
public MissingName() {
super("Your name is required.");
}
}

モデル化されたフォルトのWSDLファイルにおけるマッピングの仕組み

JAX-WSのJava-to-WSDLマッピングにより、java.lang.Exceptionのサブクラスがwsdl:faultメッセージにバインドされます。例16-4は、例16-3のアノテーション付きのWebサービスから生成されたWSDLを示しています。*

この例の内容:

- <message name="MissingName">要素は、MissingNameメッセージのパート、すなわちfaultと、関連付けられたデータ型tns:MissingNameを定義しています。

<message name="MissingName">
<part name="fault" element="tns:MissingName" />
</message>

- MissingName SOAPフォルトは、sayHelloWorld操作にマップされています。

<operation name="sayHelloWorld">
<input message="tns:sayHelloWorld" />
<output message="tns:sayHelloWorldResponse" />
<fault message="tns:MissingName" name="MissingName" />
</operation>

この例の<fault>サブ要素は、sayHelloWorld()メソッド宣言のthrows MissingName句から導出されています(例16-3を参照)。

public String sayHelloWorld(String message) throws MissingName {
...
}

- フォルト・メッセージは、<binding>要素のsayHelloWorld操作にもマップされます。

<fault name="MissingName">
<soap:fault name="MissingName" use="literal" />
</fault>

例16-5 モデル化された例外を使用したWSDLの例

<?xml version="1.0" encoding="UTF-8" ?>
<definitions
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://examples/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://examples/"
name="HelloWorldService">
<types>
<xsd:schema>
<xsd:import namespace="http://examples/"
schemaLocation="http://localhost:7001/HelloWorld/HelloWorldService?xsd=1"/>
</xsd:schema>
</types>
<message name="sayHelloWorld">
<part name="parameters" element="tns:sayHelloWorld" />
</message>
<message name="sayHelloWorldResponse">
<part name="parameters" element="tns:sayHelloWorldResponse" />
</message>
<message name="MissingName">
<part name="fault" element="tns:MissingName" />
</message>
<portType name="HelloWorld">
<operation name="sayHelloWorld">
<input message="tns:sayHelloWorld" />
<output message="tns:sayHelloWorldResponse" />
<fault message="tns:MissingName" name="MissingName" />
</operation>
</portType>
<binding name="HelloWorldPortBinding" type="tns:HelloWorld">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document" />
<operation name="sayHelloWorld">
<soap:operation soapAction="" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
<fault name="MissingName">
<soap:fault name="MissingName" use="literal" />
</fault>
</operation>
</binding>
<service name="HelloWorldService">
<port name="HelloWorldPort" binding="tns:HelloWorldPortBinding">
<soap:address
location="http://localhost:7001/HelloWorld/HelloWorldService" />
</port>
</service>

SOAPメッセージによるフォルト通知の仕組み

例16-6は、MissingName Java例外がスローされた場合に、生成されたSOAPメッセージでSOAPフォルトが通知される仕組みを示しています。

例16-6 MissingName例外のSOAPフォルト・メッセージの例

<?xml version = '1.0' encoding = 'UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
<faultcode>S:Server</faultcode>
<faultstring>Your name is required.</faultstring>
<detail>
<ns2:MissingName xmlns:ns2="http://examples/">
<message>Your name is required.</message>
</ns2:MissingName>
<ns2:exception xmlns:ns2="http://jax-ws.dev.java.net/"
class="examples.MissingName" note="To disable this feature, set
com.sun.xml.ws.fault.SOAPFaultBuilder.disableCaptureStackTrace system
property to false">
<message>Your name is required.</message>
<ns2:stackTrace>
<ns2:frame class="examples.HelloWorld" file="HelloWorld.java"
line="14" method="sayHelloWorld"/>
...
</ns2:stackTrace>
</ns2:exception>
</detail>
</S:Fault>
</S:Body>
</S:Envelope>

Webサービス・クライアントの作成

clientgenを使用して、マップされたフォルトを含むWSDLファイルからWebサービス・クライアントを生成すると、必要な例外クラス(マップされた例外、フォルトBean、サービス実装クラス、クライアント実装クラスなど)が自動的に生成されますが、それらの例外クラスは変更する必要があります。次の項では、その手順について説明します。

- 生成されたJava例外クラスの確認

- 生成されたJavaフォルトBeanクラスの確認

- クライアント側のサービス実装の確認

- クライアント実装クラスの作成

clientgenの詳細は、『Oracle WebLogic Server WebLogic Webサービス・リファレンス』のclientgenに関する項を参照してください。

生成されたJava例外クラスの確認

生成されたJava例外クラスの例を例16-7に示します。@WebFaultアノテーションは、このクラスをマップされた例外として指定しています。

例16-7 生成されたJava例外クラスの例

package examples.client;

import javax.xml.ws.WebFault;

@WebFault(name = "MissingName", targetNamespace = "http://examples/")
public class MissingName_Exception extends Exception {
private MissingName faultInfo;
public MissingName_Exception(String message, MissingName faultInfo) { ... }
public MissingName_Exception(String message, MissingName faultInfo,
Throwable cause) { ... }
public MissingName getFaultInfo() { ... }
}

生成されたJavaフォルトBeanクラスの確認

生成されたJavaフォルトBeanクラスの例を例16-8に示します。このクラスには、フォルト・メッセージのgetterとsetterが定義されています。

例16-8 生成されたJavaフォルトBeanクラスの例

package examples.client;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "MissingName", propOrder = {
"message"
})
public class MissingName {

protected String message;

public String getMessage() {
return message;
}

public void setMessage(String value) {
this.message = value;
}
}

クライアント側のサービス実装の確認

生成されたクライアント側サービス実装クラスの例を例16-9に示します。

例16-9 クライアント側のサービス実装

package examples.client;
...
@WebService(name = "HelloWorld", targetNamespace = "http://examples/")
@XmlSeeAlso({
ObjectFactory.class
})
public interface HelloWorld {

@WebMethod
@WebResult(targetNamespace = "")
@RequestWrapper(localName = "sayHelloWorld",
targetNamespace = "http://examples/",
className = "examples.client.SayHelloWorld")
@ResponseWrapper(localName = "sayHelloWorldResponse",
targetNamespace = "http://examples/",
className = "examples.client.SayHelloWorldResponse")
public String sayHelloWorld(
@WebParam(name = "arg0", targetNamespace = "")
String arg0)
throws MissingName_Exception;
}

クライアント実装クラスの作成

Webサービス・メソッドを呼び出し、カスタム例外をスローするクライアント実装クラスを作成します。続いて、そのクライアントをコンパイルし、実行します。Webサービス・クライアントの作成に関する詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebサービスの呼出しに関する項を参照してください。

例16-10に、クライアント実装クラスの例を示します。

例16-10 クライアント実装クラス

package examples.client;

import javax.xml.namespace.QName;
import java.net.MalformedURLException;
import java.net.URL;
import examples.client.MissingName_Exception;

public class Main {

public static void main(String[] args) throws MissingName_Exception {
HelloWorldService service;

try {
service = new HelloWorldService(new URL(args[0] + "?WSDL"),
new QName("http://examples/", "HelloWorldService") );
} catch (MalformedURLException murl) { throw new RuntimeException(murl); }
HelloWorld port = service.getHelloWorldPort();

String result = null;
try {
result = port.sayHelloWorld("");
} catch (MissingName_Exception e) {
System.err.println("Error: " + e);
}
System.out.println( "Got result: " + result );
}
}

モデル化されていないフォルトの使用

前述したように、モデル化されていないフォルトは、WSDLにビジネス・ロジック・フォルトが定義されていない場合は、実行時に生成される例外(java.lang.RuntimeExceptionなど)にマップされます。この場合、Java例外は汎用的なSOAPフォルト例外であるjavax.xml.ws.soap.SOAPFaultExceptionとして表されます。

次の例では、モデル化されていないフォルトにマップされた例外を示します。

例16-11 モデル化されていないフォルトを使用したWebサービスの例

package examples;

import javax.jws.WebService;
@WebService(name="HelloWorld", serviceName="HelloWorldService")
public class HelloWorld {
public String sayHelloWorld(String message) throws MissingName {
System.out.println("Say Hello World: " + message);
if (message == null || message.isEmpty()) {
throw new MissingName(); // Modeled fault
} else if (message.equalsIgnoreCase("abc")) {
throw new RuntimeException("Please enter a name."); //Unmodeled fault
}

return "Here is the message: '" + message + "'";
}
}

この例では、文字列「abc」がメソッドに渡されると、次のSOAPFaultExceptionメッセージおよびRuntimeExceptionメッセージが次のようにログ・ファイルに返されます。

例16-12 モデル化されていないフォルトのログ・ファイル・メッセージの例

...
run:
[java] Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Please
enter a name.
...
Caused by: java.lang.RuntimeException: Please enter a name.\
...

例外処理プロセスのカスタマイズ

SOAPメッセージ・ハンドラを使用して、SOAPフォルトの処理プロセスをカスタマイズできます。SOAPメッセージ・ハンドラは、Webサービスのリクエストとレスポンスの両方でSOAPメッセージをインターセプトするメカニズムです。SOAPメッセージ・ハンドラを作成すると、WebサービスおよびクライアントがSOAPメッセージの追加処理を実行できるようになります。詳細は、第17章「SOAPメッセージ・ハンドラの作成と使用」を参照してください。

SOAPフォルトからのスタック・トレースの無効化

注意:

com.sun.xml.ws.fault.SOAPFaultBuilder.disableCaptureStackTraceプロパティは、JDK 6.0の拡張としてサポートされています。このAPIはJDK 6.0キットの一部としては提供されないため、変更される可能性があります。

デフォルトでは、スタック・トレース全体(ネスト例外を含む)が、SOAPフォルト・メッセージの詳細に含まれます。たとえば、次の例は、スタック・トレースが含まれるSOAPフォルト・メッセージを示しています。

例16-13 SOAPフォルト・メッセージのスタック・トレースの例

<?xml version = '1.0' encoding = 'UTF-8'?>
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">
<S:Body>
<S:Fault xmlns:ns4="http://schemas.xmlsoap.org/soap/envelope/">
<S:Code>
<S:Value>S:Receiver</S:Value>
</S:Code>
<S:Reason>
<S:Text xml:lang="en">String index out of range: 3</S:Text>
</S:Reason>
<S:Detail>
<ns2:exception xmlns:ns2="http://jax-ws.dev.java.net/"
class="java.lang.StringIndexOutOfBoundsException" note="To disable this feature, set
com.sun.xml.ws.fault.SOAPFaultBuilder.disableCaptureStackTrace system property
to false">
<message>String index out of range: 3</message>
<ns2:stackTrace>
<ns2:frame class="java.lang.String" file="String.java" line="1934"
method="substring"/>
<ns2:frame class="ratingservice.CreditRating" file="CreditRating.java"
line="21" method="processRating"/>
<ns2:frame class="sun.reflect.NativeMethodAccessorImpl"
file="NativeMethodAccessorImpl.java" line="native" method="invoke0"/>
<ns2:frame class="sun.reflect.NativeMethodAccessorImpl"
file="NativeMethodAccessorImpl.java" line="39" method="invoke"/>
<ns2:frame class="sun.reflect.DelegatingMethodAccessorImpl"
file="DelegatingMethodAccessorImpl.java" line="25" method="invoke"/>
<ns2:frame class="java.lang.reflect.Method" file="Method.java" line="597"
method="invoke"/>
...
</ns2:stackTrace>
</ns2:exception>
</S:Detail>
</S:Fault>
</S:Body>
</S:Envelope>

Java起動プロパティcom.sun.xml.ws.fault.SOAPFaultBuilder.disableCaptureStackTraceをfalseに設定することで、スタック・トレースがSOAPフォルト・メッセージに含まれないようにすることができます。

スタック・トレースを無効にするには:

1. WL_HOMEuser_projects/domainsdomainName/startWebLogic.cmdファイルで、次のエントリをみつけます。WL_HOMEは、WebLogic Serverのメイン・インストール・ディレクトリです。

set JAVA_OPTIONS=%SAVE_JAVA_OPTIONS%

2. エントリを次のように編集します。

set JAVA_OPTIONS=-Dcom.sun.xml.ws.fault.SOAPFaultBuilder.disableCaptureStackTrace=false %SAVE_JAVA_OPTIONS%

3. startWebLogic.cmdファイルを保存します。

その他の例外

Webサービスで明示的にスローされるカスタム例外、およびビジネス・ロジックでキャッチされない例外のマッピングに使用されるSOAPFaultExceptionsに加えて、この他に2つの例外があります。これらの例外は、Webサービス・クライアントに通知される可能性があるため、確認しておく必要があります。

表16-3 その他の例外

例外

説明

javax.xml.ws.WebServiceException

すべてのJAX-WS APIランタイム例外の基本例外。JAX-WS Javaクラス(Service.BindingProvider、Dispatchなど)の呼出しに失敗した場合に使用されます。

java.util.concurrent.ExecutionException

クライアントが非同期呼出しからレスポンスを取得する際に、JAX-WS非同期呼出しで使用されます。

17 SOAPメッセージ・ハンドラの作成と使用

この章では、Java API for XML Web Services(JAX-WS)を使用したWebLogic WebサービスでSOAPメッセージ・ハンドラを作成および使用する方法について説明します。

この章の内容は以下のとおりです。

- SOAPメッセージ・ハンドラの概要

- サーバー側SOAPメッセージ・ハンドラの追加:主な手順

- クライアント側SOAPメッセージ・ハンドラの追加:主な手順

- SOAPメッセージ・ハンドラおよびハンドラ・チェーンの設計

- SOAPメッセージ・ハンドラの作成

- JWSファイルでのハンドラ・チェーンの構成

- ハンドラ・チェーン構成ファイルの作成

- Webサービスのコンパイルと再ビルド

- クライアント側SOAPメッセージ・ハンドラの構成

SOAPメッセージ・ハンドラの概要

Webサービスおよびそのクライアントは、メッセージのリクエストやレスポンスの追加処理において、SOAPメッセージにアクセスする必要が生じることがあります。SOAPメッセージ・ハンドラは、Webサービスのリクエストとレスポンスの両方でSOAPメッセージをインターセプトするメカニズムです。SOAPメッセージ・ハンドラを作成すると、WebサービスおよびクライアントがSOAPメッセージの追加処理を実行できるようになります。

ハンドラ使用の簡単な例としては、SOAPメッセージのヘッダー部分の情報へのアクセスがあります。SOAPのヘッダーを使用してWebサービス固有の情報を格納しておき、ハンドラを使用してその情報を操作することができます。

SOAPメッセージ・ハンドラは、Webサービスのパフォーマンスを向上させるために使用することもできます。Webサービスがデプロイされてしばらくすると、同じパラメータを使用してWebサービスを呼び出すコンシューマが多いことに気付く場合があります。よく使用されるWebサービス呼出しの結果をキャッシュしておき(結果が静的であることが前提となります)、適宜、キャッシュしておいた結果をただちに戻すことによって、Webサービスを実装したバックエンド・コンポーネントを呼び出す必要がなくなり、Webサービスのパフォーマンスが向上します。このパフォーマンスの向上は、ハンドラを使用して、SOAPリクエスト・メッセージに頻繁に使用されるパラメータが含まれていないかチェックすることで実現できます。

JAX-WSでは、SOAPハンドラと論理ハンドラという2つのタイプのSOAPメッセージ・ハンドラがサポートされます。SOAPハンドラは、メッセージのヘッダーや本文を含め、SOAPメッセージ全体にアクセスできます。論理ハンドラは、メッセージのペイロードにのみアクセスでき、メッセージ内のプロトコル固有の情報(たとえばヘッダー)を変更することはできません。

注意:

SOAPハンドラは、着信メッセージに(セキュリティ、WS-ReliableMessaging、MTOMなど)ポリシーと一緒に使用した場合、ユーザー定義のメッセージ・ハンドラの実行前に、ポリシーのインターセプタが実行されます。発信メッセージの場合、この順序は逆になります。

サーバー側SOAPメッセージ・ハンドラの追加:主な手順

次の手順では、WebサービスにSOAPメッセージ・ハンドラを追加する手順を大まかに説明します。

Webサービスを実装する基本的なJWSファイルを作成済であり、SOAPメッセージ・ハンドラおよびハンドラ・チェーンを追加してWebサービスを更新することが前提となっています。また、Antベースの開発環境を設定済であり、かつjwsc Antタスクを実行するためのターゲットを含む、作業用のbuild.xmlファイルがあることも前提となっています。詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』を参照してください。

- 使用例とサンプル

- WebLogic Webサービスの開発

- JWSファイルのプログラミング

- Webサービスの呼出し

表17-1 WebサービスへのSOAPメッセージ・ハンドラの追加手順

#

手順

説明

1

ハンドラとハンドラ・チェーンを設計します。

SOAPメッセージ・ハンドラを設計し、ハンドラ・チェーン内でグループ化します。「SOAPメッセージ・ハンドラおよびハンドラ・チェーンの設計」を参照してください。

2

ハンドラ・チェーン内のハンドラごとに、SOAPメッセージ・ハンドラ・インタフェースを実装するJavaクラスを作成します。

「SOAPメッセージ・ハンドラの作成」を参照してください。

3

SOAPメッセージ・ハンドラを構成するためのアノテーションを追加して、JWSファイルを更新します。

「JWSファイルでのハンドラ・チェーンの構成」を参照してください。

4

ハンドラ・チェーン構成ファイルを作成します。

「ハンドラ・チェーン構成ファイルの作成」を参照してください。

5

ハンドラ・チェーン内のすべてのハンドラ・クラスをコンパイルし、Webサービスを再ビルドします。

「Webサービスのコンパイルと再ビルド」を参照してください。

クライアント側SOAPメッセージ・ハンドラの追加:主な手順

クライアント側SOAPメッセージ・ハンドラは、スタンドアロン・クライアントと、WebLogic Server内部で実行されるクライアントの、双方のために構成できます。実際のJavaクライアント側ハンドラは、サーバー側ハンドラと同じ方法、つまり、SOAPメッセージ・ハンドラ・インタフェースを実装するJavaクラスを作成する方法で作成できます。多くの場合、WebLogic Serverで実行されるWebサービスとそのWebサービスを呼び出すクライアント・アプリケーションで、同じハンドラ・クラスを使用できます。たとえば、サーバーおよびクライアント用として、送信および受信したすべてのSOAPメッセージをログに記録する汎用ロギング・ハンドラ・クラスを記述できます。

次の手順では、Webサービス操作を呼び出すクライアント・アプリケーションにクライアント側SOAPメッセージ・ハンドラを追加する手順を大まかに説明します。

デプロイされたWebサービスを呼び出すクライアント・アプリケーションを作成済であり、クライアント側SOAPメッセージ・ハンドラおよびハンドラ・チェーンを追加してクライアント・アプリケーションを更新することを想定しています。また、Antベースの開発環境を設定済であり、かつclientgen Antタスクを実行するためのターゲットを含む、作業用のbuild.xmlファイルがあることが前提となっています。詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のスタンドアロン・クライアントからのWebサービスの呼出し: 主な手順に関する項を参照してください。

表17-2 Webサービス・クライアントにSOAPメッセージ・ハンドラを追加する手順

#

手順

説明

1

ハンドラとハンドラ・チェーンを設計します。

この手順は、サーバー側SOAPメッセージ・ハンドラを設計する手順と似ていますが、視点がWebサービスからではなくクライアント・アプリケーションからとなる点が異なります。「SOAPメッセージ・ハンドラおよびハンドラ・チェーンの設計」を参照してください。

2

ハンドラ・チェーン内のハンドラごとに、SOAPメッセージ・ハンドラ・インタフェースを実装するJavaクラスを作成します。

この手順は、サーバー側SOAPメッセージ・ハンドラを設計する手順と似ていますが、視点がWebサービスからではなくクライアント・アプリケーションからとなる点が異なります。ハンドラ・クラスのプログラミングの詳細は、「SOAPメッセージ・ハンドラの作成」を参照してださい。

3

クライアントを更新して、SOAPメッセージ・ハンドラをプログラム的に構成します。

「クライアント側SOAPメッセージ・ハンドラの構成」を参照してください。

4

アプリケーションのビルドに使用するbuild.xmlファイルを更新して、clientgen Antタスクにカスタマイズ・ファイルを指定します。

「Webサービスのコンパイルと再ビルド」を参照してください。

5

適切なタスクを実行して、クライアント・アプリケーションを再ビルドします。

prompt> ant build-client

次回クライアント・アプリケーションを実行したときには、SOAPリクエスト・メッセージの送信前とレスポンスの受信後に、構成ファイルに記述したSOAPメッセージ・ハンドラが自動的に実行されます。

注意:

clientgen Antタスクにハンドラの構成ファイルが指定されている限り、クライアント側SOAPメッセージ・ハンドラを呼び出すために実際のクライアント・アプリケーションを更新する必要はありません。ハンドラは、生成されたインタフェースによって自動的に正しい順序で実行されます。

SOAPメッセージ・ハンドラおよびハンドラ・チェーンの設計

SOAPメッセージ・ハンドラを設計するときには、以下の事項を決定する必要があります。

- 作業を実行するために必要なハンドラの数

- 実行の順序

ハンドラ・チェーン内でSOAPメッセージ・ハンドラをグループ化します。ハンドラ・チェーン内の各ハンドラには、着信メッセージと発信メッセージ両方のメソッドを定義できます。

ただし、着信メッセージと発信メッセージで同じタイプの処理が必要となるため、通常は各SOAPメッセージ・ハンドラにリクエストSOAPメッセージとレスポンスSOAPメッセージを処理する別個のメソッドを定義します。一方、SOAPリクエストのみを処理し、それと同等のレスポンス処理は行わないハンドラを設計することもできます。また、ハンドラ・チェーン内の次のハンドラを呼び出さず、そのまま、任意の時点でクライアント・アプリケーションにレスポンスを送信することも可能です。

サーバー側ハンドラの実行

Webサービスを呼び出すときに、WebLogic Serverは次のようにハンドラを実行します。

1. ハンドラ・チェーン内のハンドラのinboundメソッドはすべて、JWSアノテーションで指定されている順序で実行されます。これらのinboundメソッドのいずれもが、SOAPのリクエスト・メッセージを変更できます。

2. ハンドラ・チェーン内の最後のハンドラが実行されると、WebLogic Serverは、Webサービスを実装するバックエンド・コンポーネントを呼び出し、最終的なSOAPのリクエスト・メッセージを渡します。

3. バックエンド・コンポーネントの実行が終了したら、ハンドラ・チェーン内のハンドラのoutboundメソッドが、JWSアノテーションで指定されているのとは逆の順序で実行されます。これらのoutboundメソッドのいずれもが、SOAPのレスポンス・メッセージを変更できます。

4. ハンドラ・チェーン内の最初のハンドラが実行されると、WebLogic Serverは、Webサービスを呼び出したクライアント・アプリケーションに最終的なSOAPレスポンス・メッセージを戻します。

たとえば、JWSファイルで@HandlerChain JWSアノテーションを使用して外部構成ファイルを指定することになっており、その構成ファイルでは、次の例に示す3つのハンドラが格納されたSimpleChainというハンドラ・チェーンを定義していると仮定します。

<?xml version="1.0" encoding="UTF-8" ?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
<handler-chain>
<handler>
<handler-class>
Handler1
</handler-class>
</handler>
</handler-chain>
<handler-chain>
<handler>
<handler-class>
Handler2
</handler-class>
</handler>
</handler-chain>
<handler-chain>
<handler>
<handler-class>
Handler3
</handler-class>
</handler>
</handler-chain>
</handler-chains>

次の図は、WebLogic Serverで各ハンドラのinboundメソッドとoutboundメソッドが実行される順序を示しています。

図17-1 ハンドラ・メソッドの実行順序

「図17-1ハンドラ・メソッドの実行順序」の説明

クライアント側ハンドラの実行

クライアント側ハンドラの場合は、以下のタイミングで二度実行されます。

- クライアント・アプリケーションがWebサービスにSOAPリクエストを送信する直前

- クライアント・アプリケーションがWebサービスからSOAPレスポンスを受信した直後

SOAPメッセージ・ハンドラの作成

SOAPメッセージ・ハンドラには2つのタイプがあります。次の表にそれぞれの定義を示します。

表17-3 SOAPメッセージ・ハンドラのタイプ

ハンドラ・タイプ

説明

SOAPハンドラ

ヘッダーを含めたSOAPメッセージ全体へのアクセスを可能にします。SOAPハンドラは、javax.xml.ws.handler.soap.SOAPHandlerインタフェースを使用して定義します。呼出しには、javax.xml.ws.handler.MessageContextを拡張したjavax.xml.ws.handler.soap.SOAPMessageContextのインポートを使用します。SOAPMessageContext.getMessage()メソッドは、javax.xml.soap.SOAPMessageを返します。

論理ハンドラ

メッセージのペイロードへのアクセスを提供します。メッセージ内のプロトコル固有の情報(たとえばヘッダー)を変更することはできません。論理ハンドラは、javax.xml.ws.handler.LogicalHandlerインタフェースを使用して定義します。(http://download.oracle.com/javaee/5/api/javax/xml/ws/handler/LogicalHandler.htmlを参照してください)。呼出しには、javax.xml.ws.handler.MessageContextを拡張したjavax.xml.ws.handler.LogicalMessageContextを使用します。LogicalMessageContext.getMessage()メソッドは、javax.xml.ws.LogicalMessageを返します。

ペイロードには、JAXBオブジェクトまたはjavax.xml.transform.Sourceオブジェクトとしてアクセスできます。(http://download.oracle.com/javaee/5/api/javax/xml/ws/LogicalMessage.htmlを参照)。

両方のタイプのメッセージ・ハンドラが拡張するjavax.xml.ws.Handlerインタフェースは、次の表に示すメソッドを定義します。(http://download.oracle.com/javaee/5/api/javax/xml/ws/handler/Handler.htmlを参照)。

表17-4 ハンドラ・インタフェース・メソッド

メソッド

説明

handleMessage()

着信および発信メッセージの通常処理を管理します。MessageContextオブジェクトのプロパティは、メッセージが着信か発信かを識別するために使用します。「Handler.handleMessage()メソッドの実装」を参照してください。

handleFault()

着信および発信メッセージのフォルト処理を管理します。「Handler.handleFault()メソッドの実装」を参照してください。

close()

メッセージ交換を完了し、処理の間にアクセスしたリソースをクリーンアップします。「Handler.close()メソッドの実装」を参照してください。

また、@javax.annotation.PostConstructおよび@javax.annotation.PreDestroyアノテーションを使用すると、ハンドラが作成された後に実行するメソッドとハンドラが破棄される前に実行するメソッドを指定できます。

特に画像などの添付ファイルを処理する場合などには、ハンドラ内から直接SOAPメッセージを表示または更新しなければならない場合もあります。この場合は、(http://java.sun.com/webservices/saaj/docs.html)のSOAP With Attachments API for Java 1.1 (SAAJ)仕様の構成要素であるjavax.xml.soap.SOAPMessage抽象クラスを使用します。詳細については、「SAAJを使用したSOAPリクエスト・メッセージおよびレスポンス・メッセージの直接操作」を参照してください。

SOAPハンドラのサンプル

次に、単純なSOAPハンドラのサンプルを示します。このハンドラは、メッセージの内容とともに、メッセージが着信か発信かを返します。

package examples.webservices.handler;

import java.util.Set;
import java.util.Collections;
import javax.xml.namespace.QName;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import javax.xml.soap.SOAPMessage;

public class Handler1 implements SOAPHandler<SOAPMessageContext>
{
public Set<QName> getHeaders()
{
return Collections.emptySet();
}

public boolean handleMessage(SOAPMessageContext messageContext)
{
Boolean outboundProperty = (Boolean)
messageContext.get (MessageContext.MESSAGE_OUTBOUND_PROPERTY);

if (outboundProperty.booleanValue()) {
System.out.println("\nOutbound message:");
} else {
System.out.println("\nInbound message:");
}

System.out.println("** Response: "+messageContext.getMessage().toString());
return true;
}

public boolean handleFault(SOAPMessageContext messageContext)
{
return true;
}

public void close(MessageContext messageContext)
{
}
}

論理ハンドラのサンプル

次に、単純な論理ハンドラのサンプルを示します。このハンドラは、メッセージの内容とともに、メッセージが着信か発信かを返します。

package examples.webservices.handler;

import java.util.Set;
import java.util.Collections;
import javax.xml.namespace.QName;
import javax.xml.ws.handler.LogicalHandler;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.LogicalMessageContext;
import javax.xml.ws.LogicalMessage;
import javax.xml.transform.Source;

public class Handler2 implements LogicalHandler<LogicalMessageContext>
{
public Set<QName> getHeaders()
{
return Collections.emptySet();
}

public boolean handleMessage(LogicalMessageContext messageContext)
{
Boolean outboundProperty = (Boolean)
messageContext.get (MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty.booleanValue()) {
System.out.println("\nOutbound message:");
} else {
System.out.println("\nInbound message:");
}

System.out.println("** Response: "+messageContext.getMessage().toString());
return true;
}

public boolean handleFault(LogicalMessageContext messageContext)
{
return true;
}

public void close(MessageContext messageContext)
{
}
}

Handler.handleMessage()メソッドの実装

Handler.handleMessage()メソッドは、バックエンド・コンポーネントによって処理される前および後に、SOAPのリクエスト・メッセージをインターセプトするために呼び出されます。そのシグネチャは次のとおりです。

public boolean handleMessage(C context)
throws java.lang.RuntimeException, java.xml.ws.ProtocolException {}

このメソッドを実装すると、バックエンド・コンポーネントによって処理される前および後に、SOAPメッセージ内のデータの暗号化/復号化などのタスクを実行できます。

Cは、javax.xml.ws.handler.MessageContextを拡張します(http://download.oracle.com/javaee/5/api/javax/xml/ws/handler/MessageContext.htmlを参照してください)。ハンドラ・チェーン内のハンドラは、MessageContextプロパティを使用して、メッセージが着信か発信かを識別し、処理状態を共有します。MessageContextのSOAPMessageContextまたはLogicalMessageContextサブインタフェースを使用すると、SOAPメッセージまたは論理メッセージの内容を取得したり設定したりできます。詳細については、「メッセージ・コンテキスト・プロパティの値とメソッドの使用」を参照してください。

SOAPメッセージのすべての処理をコーディングしたら、以下のシナリオのいずれかをコーディングします。

- trueを返すことにより、ハンドラ・リクエスト・チェーン内の次のハンドラを呼び出します。
リクエスト・チェーンの次のハンドラは、@HandlerChainアノテーションによって指定された構成ファイル内の<handler-chain>要素の次の<handler>下位要素として指定されます。

- falseを返すことにより、ハンドラ・リクエスト・チェーンの処理をブロックします。
ハンドラ・リクエスト・チェーンの処理をブロックすると、Webサービスのこの呼出しについては、バックエンド・コンポーネントは実行されなくなります。Webサービスの一部の呼出しの結果をキャッシュしてあり、そのリストに現在の呼出しも含まれている場合は、この操作が便利な場合があります。

ハンドラ・リクエスト・チェーンの処理は中断されますが、WebLogic Serverが、現在のハンドラから順に、レスポンス・チェーンを呼び出します。

- ハンドラに固有のすべての実行時エラーに対して、java.lang.RuntimeExceptionまたはjava.xml.ws.ProtocolExceptionをスローします。
WebLogic Serverは、この例外を捕捉すると、ハンドラ・リクエスト・チェーンの後続の処理を終了し、この例外をWebLogic Serverのログ・ファイルに記録した上で、このハンドラのhandleFault()メソッドを呼び出します。

Handler.handleFault()メソッドの実装

Handler.handleFault()メソッドは、SOAPメッセージ処理モデルに基づいてSOAP障害を処理します。そのシグネチャは次のとおりです。

public boolean handleFault(C context)
throws java.lang.RuntimeException, java.xml.ws.ProtocolException{}

このメソッドを実装すると、バックエンド・コンポーネントによって生成されたフォルトのほか、handleMessage()メソッドによって生成されたあらゆるSOAPフォルトの処理も扱うことができます。

Cは、javax.xml.ws.handler.MessageContextを拡張します(http://download.oracle.com/javaee/5/api/javax/xml/ws/handler/MessageContext.htmlを参照してください)。ハンドラ・チェーン内のハンドラは、MessageContextプロパティを使用して、メッセージが着信か発信かを識別し、処理状態を共有します。MessageContextのLogicalMessageContextまたはSOAPMessageContextサブインタフェースを使用すると、SOAPメッセージまたは論理メッセージの内容を取得したり設定したりできます。詳細については、「メッセージ・コンテキスト・プロパティの値とメソッドの使用」を参照してください。

SOAPフォルトのすべての処理をコーディングしたら、次のいずれかを実行します。

- trueを返すことにより、ハンドラ・チェーン内の次のハンドラのhandleFault()メソッドを呼び出します。

- falseを返すことにより、ハンドラ・フォルト・チェーンの処理をブロックします。

Handler.close()メソッドの実装

Handler.close()は、メッセージ交換を完了し、処理の間にアクセスしたリソースをクリーンアップします。そのシグネチャは次のとおりです。

public boolean close(MessageContext context) {}

メッセージ・コンテキスト・プロパティの値とメソッドの使用

SOAPメッセージ・ハンドラには、以下のコンテキスト・オブジェクトが渡されます。

表17-5 メッセージ・コンテキスト・プロパティの値

メッセージ・コンテキスト・プロパティの値

説明

javax.xml.ws.handler.LogicalMessageContext

論理ハンドラのコンテキスト・オブジェクト

javax.xml.ws.handler.soap.SOAPMessageContext

SOAPハンドラのコンテキスト・オブジェクト

各コンテキスト・オブジェクトは、javax.xml.ws.handler.MessageContextを拡張します。これにより、SOAPメッセージ・ハンドラの実行時プロパティにクライアント・アプリケーションやWebサービスからアクセスするだけでなく、Webサービスのjavax.xml.ws.WebServiceContextから直接アクセスすることも可能になります(https://jax-ws.dev.java.net/nonav/jax-ws-20-pfd/api/javax/xml/ws/WebServiceContext.htmlを参照)。

たとえば、MessageContext.MESSAGE_OUTBOUND_PROPERTYには、メッセージの方向を識別するために使用するBoolean値が格納されています。リクエストの間にこのプロパティの値をチェックすることで、メッセージが着信リクエストなのか発信リクエストなのかを識別できます。このプロパティは、クライアント側のハンドラからアクセスしたときはtrue、サーバー側のハンドラからアクセスしたときはfalseになります。

使用できるMessageContextプロパティ値の詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のMessageContextプロパティ値の使用に関する項を参照してください。

LogicalMessageContextクラスは、論理メッセージを処理する次のメソッドを定義します。詳細は、(http://download.oracle.com/javaee/5/api/javax/xml/ws/handler/LogicalMessageContext.html)のjava.xml.ws.handler.LogicalMessageContext Javadocを参照してください。

表17-6 LogicalMessageContextクラスのメソッド

メソッド

説明

getMessage()

SOAPメッセージを含むjavax.xml.ws.LogicalMessageオブジェクトを取得します。

SOAPMessageContextクラスは、SOAPメッセージを処理する次のメソッドを定義します。詳細は、(http://download.oracle.com/javaee/5/api/javax/xml/ws/handler/soap/SOAPMessageContext.html)のjava.xml.ws.handler.soap.SOAPMessageContext Javadocを参照してください。

注意:

SOAPメッセージ自体は、(http://download.oracle.com/javaee/5/api/javax/xml/soap/SOAPMessage.html)のjavax.xml.soap.SOAPMessageオブジェクトに格納されています。このオブジェクトの詳細は、「SAAJを使用したSOAPリクエスト・メッセージおよびレスポンス・メッセージの直接操作」を参照してください。

表17-7 SOAPMessageContextクラスのメソッド

メソッド

説明

getHeaders()

メッセージ・コンテキスト内のメッセージから、特定の修飾名のヘッダーを取得します。

getMessage()

SOAPメッセージを含むjavax.xml.soap.SOAPMessageオブジェクトを取得します。

getRoles()

ハンドラ・チェーンの実行に関連付けられているSOAPアクター・ロールを取得します。

setMessage()

SOAPメッセージを設定します。

SAAJを使用したSOAPリクエスト・メッセージおよびレスポンス・メッセージの直接操作

javax.xml.soap.SOAPMessage抽象クラスは、(http://java.sun.com/webservices/saaj/docs.html)のSOAP With Attachments API for Java 1.1 (SAAJ)仕様の構成要素です。このクラスは、SOAPメッセージ・ハンドラ作成時にSOAPのリクエスト・メッセージおよびレスポンス・メッセージを操作するのに使用します。この節では、SOAPMessageオブジェクトの基本構造とSOAPメッセージの表示および更新に役立つメソッドのいくつかについて説明します。

SOAPMessageオブジェクトは、SOAPPartオブジェクト(SOAP XMLドキュメントそのものが入っています)、または同オブジェクトと添付ファイルで構成されています。

SOAPMessageクラスの詳細な説明については、SAAJに関するJavadocを参照してください。

SOAPPartオブジェクト

注意:

SOAPPartオブジェクトのsetContentメソッドおよびgetContentメソッドは、javax.xml.transform.stream.StreamSourceコンテンツのみをサポートします。これらのメソッドではjavax.xml.transform.dom.DOMSourceコンテンツはサポートされません。

SOAPPartオブジェクトには、SOAPEnvelopeオブジェクトに格納されたXML SOAPドキュメントが入っています。このオブジェクトは、実際のSOAPのヘッダーと本文を取得するのに使用します。

次のJavaコードのサンプルは、Handlerクラスによって提供されたMessageContextオブジェクトからSOAPメッセージを取り出して、その各部を参照する方法を示しています。

SOAPMessage soapMessage =  messageContext.getMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
SOAPBody soapBody = soapEnvelope.getBody();
SOAPHeader soapHeader = soapEnvelope.getHeader();

AttachmentPartオブジェクト

javax.xml.soap.AttachmentPartオブジェクト(http://download.oracle.com/javaee/5/api/javax/xml/soap/AttachmentPart.htmlを参照)には、 SOAPメッセージに対するオプションの添付ファイルが入っています。添付ファイルは、SOAPメッセージの残りの部分とは異なり、XMLフォーマットの必須部分ではないので、その形式は、単純なテキストからイメージ・ファイルまで、様々です。

注意:

SOAPメッセージ・ハンドラから直接に添付ファイルjava.awt.Imageにアクセスする場合は、「SOAPメッセージ・ハンドラで画像添付ファイルの操作」で重要情報を参照してください。

添付ファイルを操作するには、SOAPMessageクラスの次のメソッドを使用します。詳細には、(http://download.oracle.com/javaee/5/api/javax/xml/soap/SOAPMessage.html)のjavax.xml.soap.SOAPMessage Javadocを参照してください。

表17-8 添付ファイルの操作に使用するSOAPMessageクラスのメソッド

メソッド

説明

addAttachmentPart()

作成されたAttachmentPartオブジェクトをSOAPMessageに追加します。

countAttachments()

このSOAPメッセージに含まれている添付ファイルの数を返します。

createAttachmentPart()

他のタイプのObjectからAttachmentPartオブジェクトを作成します。

getAttachments()

すべての添付ファイルをAttachmentPartオブジェクトとして取得し、Iteratorオブジェクトに格納します。

SOAPメッセージ・ハンドラで画像添付ファイルの操作

この項では、添付ファイルjava.awt.ImageにアクセスするSOAPメッセージ・ハンドラを作成すること、およびclientgen Antタスクによって生成されたクライアントJAX-WSポートを使用するクライアント・アプリケーションからImageが送信されていることを前提としています。

clientgen Antタスクによって生成されたクライアント・コードでは、添付ファイルjava.awt.Imageはimage/gifではなくtext/xmlのMIMEタイプで、呼び出されるWebLogic Webサービスに送信され、画像は画像を表す整数のストリームにシリアライズされます。特に、このクライアント・コードは次の形式で画像をシリアライズします。

- int width

- int height

- int[] pixels

つまり、受信したImage添付ファイルを操作するSOAPメッセージ・ハンドラでは、このデータ・ストリームをデシリアライズして元の画像を作成し直す必要があるということです。

JWSファイルでのハンドラ・チェーンの構成

@javax.jws.HandlerChainアノテーションが(この章では、簡略化のために@HandlerChainとも言います)を使用すると、Webサービスのハンドラ・チェーンを構成できます。file属性を使用して、Webサービスと関連付けるハンドラ・チェーンの構成が含まれた外部ファイルを指定します。構成には、チェーン内のハンドラのリスト、ハンドラが実行される順序、初期化パラメータなどが含まれます。

次のJWSファイルでは、@HandlerChainアノテーションの使用例を示します。関連のJavaコードは太字で示しています。

package examples.webservices.handler;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.HandlerChain;
import javax.annotation.Resource;
import javax.xml.ws.WebServiceContext;
@WebService(name = "Handler", targetNamespace = "http://example.org")
@HandlerChain(file="handler-chain.xml")
public class HandlerWS
{
@Resource
WebServiceContext ctx;
@WebMethod()
public String getProperty(String propertyName)
{
return (String) ctx.getMessageContext().get(propertyName);
}
}

このサンプルに示すように、@HandlerChainアノテーションを使用する前に、それをJWSファイルにインポートする必要があります。

@HandlerChainアノテーションのfile属性を使用し、ハンドラ・チェーンの構成情報を含む外部ファイルの名前を指定します。この属性の値はURLです。これは相対でも絶対でもかまいません。相対URLは、ファイルをコンパイルするためにjwsc Antタスクを実行した時点でのJWSファイルの場所を基準とします。

注意:

1つのJWSファイル内に複数の@HandlerChainアノテーションを指定すると、エラーになります。

外部構成ファイル作成の詳細は、「ハンドラ・チェーン構成ファイルの作成」を参照してください。

この項で説明した標準的なJWSアノテーションの詳細は、Web Services Metadata for the Java Platform仕様(http://www.jcp.org/en/jsr/detail?id=181)を参照してください。

ハンドラ・チェーン構成ファイルの作成

前の項で説明したように、Webサービスにハンドラ・チェーンを関連付けるには、JWSファイル内で@HandlerChainアノテーションを使用します。その際には、外部構成ファイルからなるハンドラ・チェーン・ファイルを作成し、ハンドラ・チェーン内のハンドラのリスト、ハンドラの実行順序、初期化パラメータなどを指定する必要があります。

このファイルはJWSファイルの外部にあるため、この単一の構成ファイルを複数のWebサービスで使用するように構成し、エンタープライズ内のすべてのWebサービスに関してハンドラ構成ファイルを標準化することができます。加えて、すべてのWebサービスを再コンパイルすることなく、ハンドラ・チェーンの構成を変更できます。

構成ファイルは、次の簡単なサンプルに示すように、XMLを使用して1つまたは複数のハンドラ・チェーンをリストします。

<?xml version="1.0" encoding="UTF-8"?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
<handler-chain>
<handler>
<handler-class>examples.webservices.handler.Handler1</handler-class>
</handler>
</handler-chain>
<handler-chain>
<handler>
<handler-class>examples.webservices.handler.Handler2</handler-class>
</handler>
</handler-chain>
</handler-chains>

このサンプルでは、2つのハンドラが<handler-class>要素で指定したクラス名でハンドラ・チェーンに実装されています。2つのハンドラは、関連のWebサービス操作の前には昇順で実行され、操作実行後には逆順で実行されます。

ハンドラによって実装されるハンドラ初期化パラメータおよびSOAPロールを指定するには、それぞれ<handler>要素の<init-param>および<soap-role>子要素を使用します。

同じハンドラ・チェーンに、論理ハンドラとSOAPハンドラを含めることができます。ハンドラ・チェーンは実行時に再び並べ替えられ、発信メッセージではすべての論理ハンドラがSOAPハンドラより前に実行され、着信メッセージではすべてのSOAPハンドラが論理ハンドラより前に実行されます。

外部構成ファイルを定義するXMLスキーマ、その作成の詳細、および他のサンプルについては、Web Services Metadata for the Java Platform仕様(http://www.jcp.org/en/jsr/detail?id=181)を参照してください。

Webサービスのコンパイルと再ビルド

この項では、Webサービスをコンパイルおよびビルドする作業用のbuild.xml Antファイルがあり、そのビルド・ファイルを更新してハンドラ・チェーンを含めることを想定しています。このbuild.xmlファイルの作成については、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebLogic Webサービスの開発に関する項を参照してください。

メッセージ・ハンドラのコンパイルとビルドが含まれるように開発環境を更新するには、以下のガイドラインに従います。

- JWSファイルに@HandlerChainアノテーションを追加したら、jwsc Antタスクを再実行してJWSファイルを再コンパイルし、新しいWebサービスを生成する必要があります。これは、JWSファイル内のアノテーションに変更を加えた場合は常に当てはまります。
JWSファイルで@HandlerChainアノテーションを使用し、jwsc Antタスクを再実行してWebサービスを再生成し、その後、外部構成ファイルのみを変更した場合は、2度目の変更を有効にするためにjwscを再実行する必要はありません。

- 以下の条件がすべて満たされていれば、jwsc AntタスクはSOAPメッセージ・ハンドラJavaファイルをハンドラ・クラスにコンパイル(およびその後それらを生成されたアプリケーションにパッケージ化)します。

- ハンドラ・クラスはJWSファイルの@HandlerChainアノテーションにおいて参照されます。

- Javaファイルはsourcepath属性で指定されたディレクトリ内に置かれます。

- クラスは現在CLASSPATH内に存在しません。

ハンドラ・クラスをjwscで自動的にコンパイルするのではなく、ユーザー側でコンパイルする場合は、jwsc Antタスクを実行する前に、コンパイルされたクラスがCLASSPATH内にあることを確認してください。

- ハンドラ・チェーンが関連付けられているWebサービスのデプロイおよび呼出しは、ハンドラ・チェーンのないWebサービスのデプロイおよび呼出しと同様に行います。唯一の相違点は、Webサービスのどの操作を呼び出す場合でも、WebLogic Webサービス・ランタイムは、操作呼出しの前と後の両方で、ハンドラ・チェーン内のハンドラを実行するということです。

クライアント側SOAPメッセージ・ハンドラの構成

クライアント側SOAPメッセージ・ハンドラは、以下のいずれかの方法で定義できます。

- ポート・ポリシーやjavax.xml.ws.Dispatchオブジェクトのように、ハンドラ・チェーンを直接javax.xml.ws.BindingProviderに設定します。例:

package examples.webservices.handler.client;

import javax.xml.namespace.QName;
import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.ws.handler.Handler;
import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
import java.util.List;

import examples.webservices.handler.Handler1;
import examples.webservices.handler.Handler2;

public class Main {
public static void main(String[] args) {
HandlerWS test;
try {
test = new HandlerWS(new URL(args[0] + "?WSDL"), new
QName("http://example.org", "HandlerWS") );
} catch (MalformedURLException murl) { throw new RuntimeException(murl); }
HandlerWSPortType port = test.getHandlerWSPortTypePort();

Binding binding = ((BindingProvider)port).getBinding();
List<Handler> handlerList = binding.getHandlerChain();
handlerList.add(new Handler1());
handlerList.add(new Handler2());
binding.setHandlerChain(handlerList);
String result = null;
result = port.sayHello("foo bar");
System.out.println( "Got result: " + result );
}
}

- Serviceインスタンスにjavax.xml.ws.handler.HandlerResolverを実装します。例:

public static class MyHandlerResolver implements HandlerResolver {
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> handlers = new ArrayList<Handler>();
// add handlers to list based on PortInfo information
return handlers;
}
}

setHandlerResolver()メソッドを使用して、Serviceインスタンスにハンドラ解決メカニズムを追加します。この場合は、Serviceインスタンスから作成されたポート・プロキシまたはDispatchオブジェクトで、HandlerResolverを使用してハンドラ・チェーンを特定します。例:

test.setHandlerResolver(new MyHandlerResolver());

- ハンドラ・チェーンの記述を格納する<binding>要素を含むカスタマイズ・ファイルを作成します。<handler-chains>要素のスキーマは、ハンドラ・チェーン・ファイル(サーバー上)とカスタマイズ・ファイルで同じものを使用します。例:

<bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
wsdlLocation="http://localhost:7001/handler/HandlerWS?WSDL"
xmlns="http://java.sun.com/xml/ns/jaxws">
<bindings node="wsdl:definitions"
xmlns:jws="http://java.sun.com/xml/ns/javaee">
<handler-chains>
<handler-chain>
<handler>
<handler-class>examples.webservices.handler.Handler1
</handler-class>
</handler>
</handler-chain>
<handler-chain>
<handler>
<handler-class>examples.webservices.handler.Handler2
</handler-class>
</handler>
</handler-chain>
</handler-chains>
</bindings>

clientgenコマンドの<binding>子要素を使用してカスタマイズ・ファイルに渡します。

18 SOAPヘッダーの送受信

この章では、Java API for XML Web Services(JAX-WS)を使用したWebLogic Webサービスで、com.sun.xml.ws.developer.WSBindingProviderから利用可能なメソッドを使用して、アウトバウンドSOAPヘッダーの送信およびインバウンドSOAPヘッダーの受信を行う方法について説明します。

この章の内容は以下のとおりです。

- SOAPヘッダーの送受信の概要

- WSBindingProviderを使用したSOAPヘッダーの送信

- WSBindingProviderを使用したSOAPヘッダーの受信

注意:

com.sun.xml.ws.developer.WSBindingProvider APIおよびcom.sun.xml.ws.api.message.Headers APIは、JDK 6.0の拡張としてサポートされています。これらのAPIはJDK 6.0キットの一部としては提供されないため、変更される可能性があります。

SOAPヘッダーの送受信の概要

プロキシまたはディスパッチ・クライアントを作成すると、そのクライアントにより、javax.xml.ws.BindingProviderインタフェースが実装されます。SOAPヘッダーを送信または受信する必要がある場合には、Webサービス・プロキシ・クライアントまたはディスパッチ・クライアントをcom.sun.xml.ws.developer.WSBindingProviderにダウンキャストし、インタフェースのメソッドを使用することで、アウトバウンドSOAPヘッダーの送信やインバウンドSOAPヘッダーの受信を行うことができます。

WSBindingProviderを使用したSOAPヘッダーの送信

com.sun.xml.ws.developer.WSBindingProviderに対してsetOutboundHeadersメソッドを使用し、SOAPヘッダーを送信します。SOAPヘッダーの作成にはcom.sun.xml.ws.api.message.Headersメソッドを使用します。

たとえば、次のコードの抜粋は、簡単な文字列値をヘッダーとして渡す方法を示しています。

例18-1 WSBindingProviderを使用したSOAPヘッダーの送信

import com.sun.xml.ws.developer.WSBindingProvider;
import com.sun.xml.ws.api.message.Headers;
import javax.xml.namespace.QName;
...
HelloService helloService = new HelloService();
HelloPort port = helloService.getHelloPort();
WSBindingProvider bp = (WSBindingProvider)port;

bp.setOutboundHeaders(
// Sets a simple string value as a header
Headers.create(new QName("simpleHeader"),"stringValue")
);
...

WSBindingProviderを使用したSOAPヘッダーの受信

com.sun.xml.ws.developer.WSBindingProviderに対してgetInboundHeadersメソッドを使用し、SOAPヘッダーを受信します。

たとえば、次のコードの抜粋は、インバウンド・ヘッダーを取得する方法を示しています。

例18-2 WSBindingProviderを使用したSOAPヘッダーの受信

import com.sun.xml.ws.developer.WSBindingProvider;
import com.sun.xml.ws.api.message.Headers;
import javax.xml.namespace.QName;
import java.util.List;
...
HelloService helloService = new HelloService();
HelloPort port = helloService.getHelloPort();
WSBindingProvider bp = (WSBindingProvider)port;

List inboundHeaders = bp.getInboundHeaders();
...

19 XMLメッセージ・レベルでの操作

この章では、Java API for XML Web Services(JAX-WS)を使用したWebLogic Webサービスで、XMLメッセージ・レベルで処理を行うWebサービス・プロバイダベース・エンドポイントおよびディスパッチ・クライアントを開発する方法を説明します。

この章の内容は以下のとおりです。

- Webサービス・プロバイダベース・エンドポイントおよびディスパッチ・クライアントの概要

- XMLレベルでの処理のための使用モードとメッセージ・フォーマット

- Webサービス・プロバイダベース・エンドポイントの開発(Javaから始める場合)

- Webサービス・プロバイダベース・エンドポイントの開発(WSDLから始める場合)

- プロバイダベース・エンドポイントでのSOAPハンドラの使用

- Webサービス・ディスパッチ・クライアントの開発

Webサービス・プロバイダベース・エンドポイントおよびディスパッチ・クライアントの概要

JAXB生成のクラスを使用する方が単純で処理速度が速く、エラーになる可能性も低いですが、場合によってはXMLメッセージ・コンテンツを直接処理するために独自のビジネス・ロジックを生成する必要があります。メッセージレベルのアクセスは、サーバー側ではWebサービス・プロバイダベース・エンドポイントを使用して、クライアント側ではディスパッチ・クライアントを使用して実行できます。

Webサービス・プロバイダベース・エンドポイントは、Javaサービス・エンドポイント・インタフェース(SEI)ベースのエンドポイントにかわる動的なエンドポイントを提供します。JavaオブジェクトとそのXML表現の変換の詳細を概念化するSEIベースのエンドポイントとは異なり、プロバイダ・インタフェースでは、JAXBバインディングなしでXMLメッセージ・レベルのコンテンツに直接アクセスできます。Webサービス・プロバイダベース・エンドポイントは、javax.xml.ws.Provider<T>またはcom.sun.xml.ws.api.server.AsyncProvider<T>インタフェースのそれぞれを使用して、同期的または非同期的に実装できます。Webサービス・プロバイダベース・エンドポイントの開発に関する詳細は、「Webサービス・プロバイダベース・エンドポイントの開発(Javaから始める場合)」を参照してください。

javax.xml.ws.Dispatch<T>インタフェースを使用して実装されるWebサービスのディスパッチ・クライアントは、クライアントがXMLレベルでメッセージを処理できるようにします。Webサービスのディスパッチ・クライアントを開発する手順は、「Webサービス・ディスパッチ・クライアントの開発」で説明します。

プロバイダ・エンドポイントとディスパッチ・クライアントは、WSDLが使用できるかぎり、次のような他のWebLogic Webサービス機能と連動して使用できます。

- WS-Security

- WS-ReliableMessaging

- WS-MakeConnection

- WS-AtomicTransaction

また、ディスパッチ・クライアントは、非同期クライアント・トランスポート機能および非同期クライアント・ハンドラ機能と組み合せて使用できます。これらの機能の詳細は第4章「Webサービスの非同期呼出し」を、コード例は「ディスパッチ・インスタンスの作成」を参照してください。

XMLレベルでの処理のための使用モードとメッセージ・フォーマット

プロバイダベース・エンドポイントまたはディスパッチ・クライアントを使用してXMLレベルでメッセージを処理するとき、次の表に定義する使用モードの1つを使用します。使用モードは、「使用モードの指定(@ServiceModeアノテーション)」の説明に従ってjavax.xml.ws.ServiceModeアノテーションを使用して定義します。

表19-1 XMLメッセージ・レベルでの処理のための使用モード

使用モード

説明

メッセージ

メッセージ全体を直接処理します。たとえば、SOAPバインディングが使用される場合、SOAPエンベロープ全体にアクセスします。

ペイロード

メッセージのペイロードのみを処理します。たとえば、SOAPバインディングが使用される場合、SOAP本体にアクセスします。

プロバイダベース・エンドポイントとディスパッチ・クライアントは、表19-2に定義されているメッセージ・フォーマットの1つを使用してメッセージを送受信できます。この表では、構成されているバインディング・タイプ(SOAP over HTTPまたはXML over HTTP)に対応する有効なメッセージ・フォーマットと使用モードの組合せも定義されます。

表19-2 XMLメッセージ・レベルでの処理でサポートされるメッセージ・フォーマット

メッセージ・フォーマット

SOAP/HTTPバインディングでサポートされる使用モード

XML/HTTPバインディングでサポートされる使用モード

javax.xml.transform.Source

メッセージ・モード: SOAPエンベロープ

ペイロード・モード: SOAP本体

メッセージ・モード: SourceとしてのXMLコンテンツ

ペイロード・モード: SourceとしてのXMLコンテンツ

javax.activation.DataSource

SOAP/HTTPバインディングの添付ファイルはSOAPMessageフォーマットを使用して送信されるため、どちらのモードでも有効ではありません。

メッセージ・モード: DataSourceオブジェクト

添付ファイルの送信にDataSourceが使用されるため、ペイロード・モードでは有効ではありません。

javax.xml.soap.SOAPMessage

メッセージ・モード: SOAPMessageオブジェクト

ペイロードのみではなくSOAPメッセージ全体が受信されるため、ペイロード・モードでは有効ではありません。

クライアントがSOAP以外のメッセージをXML/HTTPバインディングで送信できるため、どちらのモードでも有効ではありません。

Webサービス・プロバイダベース・エンドポイントの開発(Javaから始める場合)

次の項で説明されているように、同期および非同期のWebサービス・プロバイダベース・エンドポイントのどちらも開発できます。

- 同期プロバイダベース・エンドポイントの開発

- 非同期プロバイダベース・エンドポイントの開発

注意:

WSDLから始めて、ポートをWebサービス・プロバイダとして設定するには、「Webサービス・プロバイダベース・エンドポイント(WSDLから始める場合)」を参照してください。

同期プロバイダベース・エンドポイントの開発

javax.xml.ws.Provider<T>を使用して実装されるWebサービス・プロバイダベース・エンドポイントでは、JAXBバインディングを使用せずXMLメッセージ・レベルでコンテンツに直接アクセスできます。Providerインタフェースはメッセージを同期的に処理するため、サービスはレスポンス処理を待機し、その後処理を続行します。javax.xml.ws.Provider<T>インタフェースの詳細は、http://download.oracle.com/javaee/5/api/javax/xml/ws/Provider.htmlを参照してください。

次の手順では、同期Webサービス・プロバイダベース・エンドポイントを実装するJWSファイルをプログラミングするための一般的な手順を説明します。

表19-3 同期Webサービス・プロバイダベース・エンドポイントを開発する手順

#

手順

説明

1

Webサービス・プロバイダベースJWSファイルで使用するJWSアノテーションをインポートします。

Webサービス・プロバイダベースJWSファイルの標準JWSアノテーションの内容は次のとおりです。

import javax.xml.ws.Provider;
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.ServiceMode;

必要であれば他のアノテーションをインポートします。サポートされるすべてのJWSアノテーションのリストは、『Oracle WebLogic Server WebLogic Webサービス・リファレンス』の"Webサービスのアノテーションのサポートに関する項を参照してください。

2

プロバイダベースの実装クラスを開発するときは、表19-2に定義されている、サポート対象のメッセージ・フォーマットの1つを指定します。

「メッセージ・フォーマットの指定」を参照してください。

3

必須の標準@WebServiceProvider JWSアノテーションをクラス・レベルで追加して、JavaクラスがWebサービス・プロバイダを公開することを指定します。

「JWSファイルによるWebサービス・プロバイダの実装の指定(@WebServiceProviderアノテーション)」を参照してください。

4

標準@ServiceMode JWSアノテーションをクラス・レベルで追加して、Webサービス・プロバイダがメッセージ・レベルまたはメッセージ・ペイロード・レベルで情報にアクセスすることを指定します。(オプション)

「使用モードの指定(@ServiceModeアノテーション)」を参照してください。

サービス・モードのデフォルトはService.Mode.Payloadです。

5

invoke()メソッドを定義します。

invoke()メソッドは呼び出されると、指定のメッセージ・フォーマットを使用するメソッドにメッセージまたはメッセージ・ペイロードを入力として提供します。「同期プロバイダベース・エンドポイントのinvoke()メソッドの定義」を参照してください。

次のJWSファイルのサンプルでは、簡単な同期Webサービス・プロバイダベース・エンドポイントの実装方法を示します。同期Webサービス・プロバイダベース・エンドポイントの開発手順の詳細は後の項で説明します。サンプル全体の中でこのJWSファイルを確認するには、Oracle WebLogic Serverに含まれるWebサービス・サンプルのJava EEのためのJAX-WS Webサービスの作成に関する項を参照してください。

注意:

RESTfulなWebサービスは、XML/HTTPバインディングのプロバイダベース・エンドポイントを使用して構築できます。RESTfulなWebサービスでのプロバイダベース・エンドポイントのプログラミング例は、「XML over HTTPを使用するWebサービスのプログラミング」を参照してください。

例19-1 同期プロバイダベース・エンドポイントを実装するJWSファイルの例

package examples.webservices.jaxws;

import org.w3c.dom.Node;

import javax.xml.transform.Source;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.Provider;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.Service;
import java.io.ByteArrayInputStream;

/**
* A simple Provider-based Web service implementation.
*
* @author Copyright (c) 2010, Oracle and/or its affiliates.
* All Rights Reserved.
*/
// The @ServiceMode annotation specifies whether the Provider instance
// receives entire messages or message payloads.
@ServiceMode(value = Service.Mode.PAYLOAD)

// Standard JWS annotation that configures the Provider-based Web service.
@WebServiceProvider(portName = "SimpleClientPort",
serviceName = "SimpleClientService",
targetNamespace = "http://jaxws.webservices.examples/",
wsdlLocation = "SimpleClientService.wsdl")
public class SimpleClientProviderImpl implements Provider<Source> {

//Invokes an operation according to the contents of the request message.
public Source invoke(Source source) {
try {
DOMResult dom = new DOMResult();
Transformer trans = TransformerFactory.newInstance().newTransformer();
trans.transform(source, dom);
Node node = dom.getNode();
// Get the operation name node.
Node root = node.getFirstChild();
// Get the parameter node.
Node first = root.getFirstChild();
String input = first.getFirstChild().getNodeValue();
// Get the operation name.
String op = root.getLocalName();
if ("invokeNoTransaction".equals(op)) {
return sendSource(input);
} else {
return sendSource2(input);
}
}
catch (Exception e) {
throw new RuntimeException("Error in provider endpoint", e);
}
}

private Source sendSource(String input) {
String body =
"<ns:invokeNoTransactionResponse
xmlns:ns=\"http://jaxws.webservices.examples/\"><return>"
+ "constructed:" + input
+ "</return></ns:invokeNoTransactionResponse>";
Source source = new StreamSource(new ByteArrayInputStream(body.getBytes()));
return source;
}

private Source sendSource2(String input) {
String body =
"<ns:invokeTransactionResponse
xmlns:ns=\"http://jaxws.webservices.examples/\"><return>"
+ "constructed:" + input
+ "</return></ns:invokeTransactionResponse>";
Source source = new StreamSource(new ByteArrayInputStream(body.getBytes()));
return source;
}

}

非同期プロバイダベース・エンドポイントの開発

Providerインタフェースを使用する場合と同様に、com.sun.xml.ws.api.server.AsyncProvider<T>インタフェースを使用して実装されるWebサービス・プロバイダベース・エンドポイントでは、JAXBバインディングを使用せずXMLメッセージ・レベルでコンテンツに直接アクセスできます。ただし、AsyncProviderインタフェースはメッセージを非同期に処理します。そのため、サービスはスレッドをブロックすることなく処理を続行し、リクエストが使用可能になった時点でそのリクエストを処理できます。

次の手順では、非同期Webサービス・プロバイダベース・エンドポイントを実装するJWSファイルをプログラミングするための一般的な手順を説明します。

表19-4 非同期Webサービス・プロバイダベース・エンドポイントを開発する手順

#

手順

説明

1

Webサービス・プロバイダベースJWSファイルで使用するJWSアノテーションをインポートします。

非同期Webサービス・プロバイダベースJWSファイルの標準JWSアノテーションの内容は次のとおりです。

import com.sun.xml.ws.api.server.AsyncProvider;
import com.sun.xml.ws.api.server.AsyncProviderCallback;
import javax.xml.ws.ServiceMode;

必要であれば他のアノテーションをインポートします。サポートされるすべてのJWSアノテーションのリストは、『Oracle WebLogic Server WebLogic Webサービス・リファレンス』の"Webサービスのアノテーションのサポートに関する項を参照してください。

2

プロバイダベースの実装クラスを開発するときは、表19-2に定義されている、サポート対象のメッセージ・フォーマットの1つを指定します。

「メッセージ・フォーマットの指定」を参照してください。

3

必須の標準@WebServiceProvider JWSアノテーションをクラス・レベルで追加して、JavaクラスがWebサービス・プロバイダを公開することを指定します。

「JWSファイルによるWebサービス・プロバイダの実装の指定(@WebServiceProviderアノテーション)」を参照してください。

4

標準@ServiceMode JWSアノテーションをクラス・レベルで追加して、Webサービス・プロバイダがメッセージ・レベルまたはメッセージ・ペイロード・レベルで情報にアクセスすることを指定します。(オプション)

「使用モードの指定(@ServiceModeアノテーション)」を参照してください。

サービス・モードのデフォルトはService.Mode.Payloadです。

5

invoke()メソッドを定義します。

invoke()メソッドは呼び出されると、指定のメッセージ・フォーマットを使用するメソッドにメッセージまたはメッセージ・ペイロードを入力として提供します。「非同期プロバイダベース・エンドポイントのinvoke()メソッドの定義」を参照してください。

6

レスポンスを処理するための非同期ハンドラのコールバック・メソッドを定義します。

このメソッドは、レスポンスが返されたときにそのレスポンスを処理します。「非同期プロバイダベース・エンドポイントのコールバック・ハンドラの定義」を参照してください。

次のJWSファイルのサンプルでは、簡単な非同期Webサービス・プロバイダベース・エンドポイントの実装方法を示します。非同期Webサービス・プロバイダベース・エンドポイントの開発手順の詳細は後の項で説明します。

例19-2 非同期プロバイダベース・エンドポイントを実装するJWSファイルの例

package asyncprovider.server;

import com.sun.xml.ws.api.server.AsyncProvider;
import com.sun.xml.ws.api.server.AsyncProviderCallback;

import javax.xml.bind.JAXBContext;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceProvider;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

@WebServiceProvider(
wsdlLocation="WEB-INF/wsdl/hello_literal.wsdl",
targetNamespace = "urn:test",
serviceName="Hello")

public class HelloAsyncImpl implements AsyncProvider<Source> {

private static final JAXBContext jaxbContext = createJAXBContext();
private int bodyIndex;

public javax.xml.bind.JAXBContext getJAXBContext(){
return jaxbContext;
}

private static javax.xml.bind.JAXBContext createJAXBContext(){
try{
return javax.xml.bind.JAXBContext.newInstance(ObjectFactory.class);
}catch(javax.xml.bind.JAXBException e){
throw new WebServiceException(e.getMessage(), e);
}
}

private Source sendSource() {
System.out.println("**** sendSource ******");

String[] body  = {
"<HelloResponse xmlns=\"urn:test:types\">
<argument xmlns=\"\">foo</argument>
<extra xmlns=\"\">bar</extra>
</HelloResponse>",
"<ans1:HelloResponse xmlns:ans1=\"urn:test:types\">
<argument>foo</argument>
<extra>bar</extra>
</ans1:HelloResponse>",
};
int i = (++bodyIndex)%body.length;
return new StreamSource(
new ByteArrayInputStream(body[i].getBytes()));
}

private Hello_Type recvBean(Source source) throws Exception {
System.out.println("**** recvBean ******");
return (Hello_Type)jaxbContext.createUnmarshaller().unmarshal(source);
}

private Source sendBean() throws Exception {
System.out.println("**** sendBean ******");
HelloResponse resp = new HelloResponse();
resp.setArgument("foo");
resp.setExtra("bar");
ByteArrayOutputStream bout = new ByteArrayOutputStream();
jaxbContext.createMarshaller().marshal(resp, bout);
return new StreamSource(new ByteArrayInputStream(bout.toByteArray()));
}

public void invoke(Source source, AsyncProviderCallback<Source> cbak,
WebServiceContext ctxt) {
System.out.println("**** Received in AsyncProvider Impl ******");
try {
Hello_Type hello = recvBean(source);
String arg = hello.getArgument();
if (arg.equals("sync")) {
String extra = hello.getExtra();
if (extra.equals("source")) {
cbak.send(sendSource());
} else if (extra.equals("bean")) {
cbak.send(sendBean());
} else {
throw new WebServiceException("Expected extra =
(source|bean|fault), Got="+extra);
}
} else if (arg.equals("async")) {
new Thread(new RequestHandler(cbak, hello)).start();
} else {
throw new WebServiceException("Expected Argument =
(sync|async), Got="+arg);
}
} catch(Exception e) {
throw new WebServiceException("Endpoint failed", e);
}
}

private class RequestHandler implements Runnable {
final AsyncProviderCallback<Source> cbak;
final Hello_Type hello;
public RequestHandler(AsyncProviderCallback<Source> cbak, Hello_Type hello) {
this.cbak = cbak;
this.hello = hello;
}

public void run() {
try {
Thread.sleep(5000);
} catch(InterruptedException ie) {
cbak.sendError(new WebServiceException("Interrupted..."));
return;
}
try {
String extra = hello.getExtra();
if (extra.equals("source")) {
cbak.send(sendSource());
} else if (extra.equals("bean")) {
cbak.send(sendBean());
} else {
cbak.sendError(new WebServiceException(
"Expected extra = (source|bean|fault), Got="+extra));
}
} catch(Exception e) {
cbak.sendError(new WebServiceException(e));
}
}
}
}

メッセージ・フォーマットの指定

プロバイダベースの実装クラスを開発するときは、表19-2に定義されている、サポート対象のメッセージ・フォーマットの1つを指定します。

たとえば、例19-1「同期プロバイダベース・エンドポイントを実装するJWSファイルの例」に示したProviderの実装例では、SimpleClientProviderImplクラスがProvider<Source>インタフェースを実装し、入力と出力の両方の型がjava.xml.transform.Sourceオブジェクトであることを示しています。

public class SimpleClientProviderImpl implements Provider<Source> {
. . .
}

同様に、例19-2「非同期プロバイダベース・エンドポイントを実装するJWSファイルの例」に示したAsyncProviderの実装例では、HelloAsyncImplクラスがAsyncProvider<Source>インタフェースを実装し、入力と出力の両方の型がjava.xml.transform.Sourceオブジェクトであることを示しています。

public class HelloAsyncImpl implements AsyncProvider<Source>  {
. . .
}

JWSファイルによるWebサービス・プロバイダの実装の指定(@WebServiceProviderアノテーション)

次のコードの抜粋のように、標準のjavax.xml.ws.WebServiceProviderアノテーションを使用して、JWSファイルがWebサービス・プロバイダを実装することをクラス・レベルで指定します。

@WebServiceProvider(portName = "SimpleClientPort",
serviceName = "SimpleClientService",
targetNamespace = "http://jaxws.webservices.examples/",
wsdlLocation = "SimpleClientService.wsdl")

この例では、サービス名はSimpleClientServiceであり、生成されるWSDLファイルのwsdl:service要素にマップされます。ポート名はSimpleClientPortであり、生成されるWSDLファイルのwsdl:port要素にマップされます。生成されるWSDLで使用されるターゲット・ネームスペースはhttp://jaxws.webservices.examples/で、WSDLの場所はWebサービス・プロバイダに対して局所的であり、SimpleClientService.wsdlにあります。

@WebServiceProviderアノテーションの詳細は、https://jax-ws.dev.java.net/nonav/2.1.5/docs/annotations.htmlを参照してください。

使用モードの指定(@ServiceModeアノテーション)

javax.xml.ws.ServiceModeアノテーションを使用して、Webサービス・プロバイダベース・エンドポイントが、メッセージ全体を受信するか(Service.Mode.MESSAGE)、メッセージ・ペイロードのみを受信するか(Service.Mode.PAYLOAD)を指定します。

例:

@ServiceMode(value = Service.Mode.PAYLOAD)

指定しない場合、@ServiceModeアノテーションのデフォルトはService.Mode.PAYLOADです。

有効なメッセージ・フォーマットと使用モードの組合せのリストは、表19-2を参照してください。

@ServiceModeアノテーションの詳細は、https://jax-ws.dev.java.net/nonav/2.1.4/docs/annotations.htmlを参照してください。

同期プロバイダベース・エンドポイントのinvoke()メソッドの定義

Provider<T>インタフェースによって、実装クラスに定義する必要がある1つのメソッドが定義されます。

T invoke(T request)

Webサービス・リクエストが受信されると、invoke()メソッドが呼び出され、指定のメッセージ・フォーマットを使用するメソッドにメッセージまたはメッセージ・ペイロードを入力として提供します。

たとえば、「同期プロバイダベース・エンドポイントを実装するJWSファイルの例」のProviderの実装例では、次の抜粋に示すように、invokeメソッドの入力としてSourceパラメータを受け取り、Sourceレスポンスを返すようにクラスが定義されています。

public Source invoke(Source source) {
try {
DOMResult dom = new DOMResult();
Transformer trans = TransformerFactory.newInstance().newTransformer();
trans.transform(source, dom);
Node node = dom.getNode();
// Get the operation name node.
Node root = node.getFirstChild();
// Get the parameter node.
Node first = root.getFirstChild();
String input = first.getFirstChild().getNodeValue();
// Get the operation name.
String op = root.getLocalName();
if ("invokeNoTransaction".equals(op)) {
return sendSource(input);
} else {
return sendSource2(input);
}
}
catch (Exception e) {
throw new RuntimeException("Error in provider endpoint", e);
}
}

非同期プロバイダベース・エンドポイントのinvoke()メソッドの定義

AsycnProvider<T>インタフェースによって、実装クラスに定義する必要がある1つのメソッドが定義されます。

void invoke(T request, AsyncProviderCallback<t> callback, WebserviceContext context))

メソッドを呼び出すには、次のパラメータを渡します。

- 指定のフォーマットのリクエスト・メッセージまたはメッセージ・ペイロード。

- レスポンスが返されたときにそのレスポンスを処理するcom.sun.xml.ws.api.server.AsyncProviderCallback実装。詳細は、「非同期プロバイダベース・エンドポイントのコールバック・ハンドラの定義」を参照してください。

- 処理されるリクエストのメッセージ・コンテキストを定義するjavax.xml.ws.WebServiceContext。非同期プロバイダベース・エンドポイントでは、注入されたWebServiceContextは使用できません。これは、情報を返す必要のあるリクエストを判別する際に呼び出し側スレッドに依存するためです。かわりに、WebServiceContextオブジェクトを渡します。このオブジェクトは、AsyncProviderCallbackを呼び出すまで使用できます。

たとえば、例19-2「非同期プロバイダベース・エンドポイントを実装するJWSファイルの例」のAysncProviderの実装例では、次の抜粋に示すように、このクラスのinvokeメソッドが次のように定義されています。

public void invoke(Source source, AsyncProviderCallback<Source> cbak,
WebServiceContext ctxt) {
System.out.println("**** Received in AsyncProvider Impl ******");
try {
Hello_Type hello = recvBean(source);
String arg = hello.getArgument();
if (arg.equals("sync")) {
String extra = hello.getExtra();
if (extra.equals("source")) {
cbak.send(sendSource());
} else if (extra.equals("bean")) {
cbak.send(sendBean());
} else {
throw new WebServiceException("Expected extra =
(source|bean|fault), Got="+extra);
}
} else if (arg.equals("async")) {
new Thread(new RequestHandler(cbak, hello)).start();
} else {
throw new WebServiceException("Expected Argument =
(sync|async), Got="+arg);
}
} catch(Exception e) {
throw new WebServiceException("Endpoint failed", e);
}
}

非同期プロバイダベース・エンドポイントのコールバック・ハンドラの定義

AsyncProviderCallbackインタフェースには、非同期レスポンスを受信したときにそのレスポンスを処理するためのコールバック・ハンドラを定義できます。

たとえば、例19-2「非同期プロバイダベース・エンドポイントを実装するJWSファイルの例」から抜粋した次のAysncProviderの実装例では、RequestHandlerメソッドでAsyncProviderCallbackコールバック・ハンドラを使用して非同期レスポンスを処理しています。

private class RequestHandler implements Runnable {
final AsyncProviderCallback<Source> cbak;
final Hello_Type hello;
public RequestHandler(AsyncProviderCallback<Source> cbak, Hello_Type hello) {
this.cbak = cbak;
this.hello = hello;
}

public void run() {
try {
Thread.sleep(5000);
} catch(InterruptedException ie) {
cbak.sendError(new WebServiceException("Interrupted..."));
return;
}
try {
String extra = hello.getExtra();
if (extra.equals("source")) {
cbak.send(sendSource());
} else if (extra.equals("bean")) {
cbak.send(sendBean());
} else {
cbak.sendError(new WebServiceException(
"Expected extra = (source|bean|fault), Got="+extra));
}
} catch(Exception e) {
cbak.sendError(new WebServiceException(e));
}
}
}
}

Webサービス・プロバイダベース・エンドポイントの開発(WSDLから始める場合)

プロバイダベース・エンドポイントがWSDLファイルから生成される場合、<provider> WSDL拡張を使用してポートをプロバイダとしてマークできます。例:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bindings wsdlLocation="SimpleClientService.wsdl"
xmlns="http://java.sun.com/xml/ns/jaxws">
<bindings node="wsdl:definitions" >
<package name="provider.server"/>
<provider>true</provider>
</bindings>

プロバイダベース・エンドポイントでのSOAPハンドラの使用

プロバイダベース・エンドポイントは、メッセージのリクエストやレスポンスの追加処理において、SOAPメッセージにアクセスしなければならないときがあります。SEIベース・エンドポイントに実行する場合と同様に、SOAPメッセージ・ハンドラを作成し、プロバイダベース・エンドポイントがSOAPメッセージに対してこの追加処理を実行できるようにすることができます。SOAPハンドラの作成に関する詳細は、「SOAPメッセージ・ハンドラの作成」を参照してください。

表17-1「WebサービスへのSOAPメッセージ・ハンドラの追加手順」には、WebサービスにSOAPハンドラを追加する場合に必要な手順が順に記載されています。これらの手順は、Webサービス・プロバイダベース・エンドポイントにも適用できます。

例:

1. SOAPメッセージ・ハンドラを設計し、それらを1つのハンドラ・チェーンにグループ化します(「SOAPメッセージ・ハンドラおよびハンドラ・チェーンの設計」を参照)。

2. ハンドラ・チェーン内のハンドラごとに、SOAPメッセージ・ハンドラ・インタフェースを実装するJavaクラスを作成します(「SOAPメッセージ・ハンドラの作成」を参照)。
SOAPハンドラの例、MyHandlerを次に示します。

package provider.rootpart_charset_772.server;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.xml.namespace.QName;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.io.InputStream;
import java.io.OutputStream;.import java.io.ByteArrayInputStream;
import java.util.Set;

public class MyHandler implements SOAPHandler<SOAPMessageContext> {

public Set<QName> getHeaders() {
return null;
}

public boolean handleMessage(SOAPMessageContext smc) {
if (!(Boolean)smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY))
return true;
try {
SOAPMessage msg = smc.getMessage();
AttachmentPart part = msg.createAttachmentPart(getDataHandler());
part.setContentId("SOAPTestHandler@example.jaxws.sun.com");
msg.addAttachmentPart(part);
msg.saveChanges();
smc.setMessage(msg);
} catch (Exception e) {
throw new WebServiceException(e);
}
return true;
}

public boolean handleFault(SOAPMessageContext context) {
return true;
}

public void close(MessageContext context) {}

private DataHandler getDataHandler() throws Exception {
return new DataHandler(new DataSource() {
public String getContentType() {
return "text/xml";
}

public InputStream getInputStream() {
return new ByteArrayInputStream("<a/>".getBytes());
}

public String getName() {
return null;
}

public OutputStream getOutputStream() {
throw new UnsupportedOperationException();
}
});
}
}

3. @javax.jws.HandlerChainアノテーションをProvider実装に追加します(「JWSファイルでのハンドラ・チェーンの構成」を参照)。
例:

package provider.rootpart_charset_772.server;

import javax.jws.HandlerChain;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.*;
import java.io.ByteArrayInputStream;

@WebServiceProvider(targetNamespace="urn:test", portName="HelloPort", serviceName="Hello")
@ServiceMode(value=Service.Mode.MESSAGE)
@HandlerChain(file="handlers.xml")
public class SOAPMsgProvider implements Provider<SOAPMessage> {

public SOAPMessage invoke(SOAPMessage msg) {
try {
// keeping white space in the string is intentional
String content = "<soapenv:Envelope
xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">
<soapenv:Body>  <VoidTestResponse
xmlns=\"urn:test:types\">
</VoidTestResponse></soapenv:Body></soapenv:Envelope>";
Source source = new StreamSource(new
ByteArrayInputStream(content.getBytes()));
MessageFactory fact = MessageFactory.newInstance();
SOAPMessage soap = fact.createMessage();
soap.getSOAPPart().setContent(source);
soap.getMimeHeaders().addHeader("foo", "bar");
return soap;
} catch(Exception e) {
throw new WebServiceException(e);
}
}
}

4. ハンドラ・チェーン構成ファイルを作成します(「ハンドラ・チェーン構成ファイルの作成」を参照)。
ハンドラ・チェーン構成ファイルの例(handlers.xml)を次に示します。

<handler-chains xmlns='http://java.sun.com/xml/ns/javaee'>
<handler-chain>
<handler>
<handler-name>MyHandler</handler-name>
<handler-class>
provider.rootpart_charset_772.server.MyHandler
</handler-class>
</handler>
</handler-chain>
</handler-chains>

5. ハンドラ・チェーン内のすべてのハンドラ・クラスをコンパイルし、Webサービスを再ビルドします(「Webサービスのコンパイルと再ビルド」を参照)。

Webサービス・ディスパッチ・クライアントの開発

javax.xml.ws.Dispatch<T>インタフェースを使用して実装されるWebサービス・ディスパッチ・クライアントでは、クライアントがXMLレベルでメッセージを処理できます。

次の手順では、Webサービス・ディスパッチ・クライアントをプログラミングするための一般的な手順を説明します。

表19-5 Webサービス・プロバイダベース・エンドポイントを開発する手順

#

手順

説明

1

Webサービス・プロバイダベースJWSファイルで使用するJWSアノテーションをインポートします。

Webサービス・プロバイダベースJWSファイルの標準JWSアノテーションの内容は次のとおりです。

import javax.xml.ws.Service;
import javax.xml.ws.Dispatch;
import javax.xml.ws.ServiceMode;

必要であれば他のアノテーションをインポートします。サポートされるすべてのJWSアノテーションのリストは、『Oracle WebLogic Server WebLogic Webサービス・リファレンス』の"Webサービスのアノテーションのサポートに関する項を参照してください。

2

Dispatchインスタンスを作成します。

「ディスパッチ・インスタンスの作成」を参照してください。

3

Webサービス操作を呼び出します。

Webサービス操作は、同期(一方向または双方向)または非同期(ポーリングまたは非同期ハンドラ)で呼び出すことができます。「Webサービス操作の呼出し」を参照してください。

Webサービス・ディスパッチ・クライアントの例

次のサンプルは、基本的なWebサービス・ディスパッチ・クライアントがどのように実装されるかを示します。このサンプルの詳細は後の項で説明します。

例19-3 Webサービス・ディスパッチ・クライアントの例

package jaxws.dispatch.client;

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.net.URL;

import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.xml.ws.WebServiceException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
import javax.xml.ws.soap.SOAPBinding;

public class WebTest extends TestCase {
private static String in_str = "wiseking";
private static String request =
"<ns1:sayHello xmlns:ns1=\"http://example.org\"><arg0>"+in_str+"</arg0></ns1:sayHello>";

private static final QName portQName = new QName("http://example.org", "SimplePort");
private Service service = null;

protected void setUp() throws Exception {

String url_str = System.getProperty("wsdl");
URL url = new URL(url_str);
QName serviceName = new QName("http://example.org", "SimpleImplService");
service = Service.create(serviceName);
service.addPort(portQName, SOAPBinding.SOAP11HTTP_BINDING, url_str);
System.out.println("Setup complete.");

}

public void testSayHelloSource() throws Exception {
setUp();
Dispatch<Source> sourceDispatch =
service.createDispatch(portQName, Source.class, Service.Mode.PAYLOAD);
System.out.println("\nInvoking xml request: " + request);
Source result = sourceDispatch.invoke(new StreamSource(new StringReader(request)));
String xmlResult = sourceToXMLString(result);
System.out.println("Received xml response: " + xmlResult);
assertTrue(xmlResult.indexOf("HELLO:"+in_str)>=0);
}

private String sourceToXMLString(Source result) {
String xmlResult = null;
try {
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
OutputStream out = new ByteArrayOutputStream();
StreamResult streamResult = new StreamResult();
streamResult.setOutputStream(out);
transformer.transform(result, streamResult);
xmlResult = streamResult.getOutputStream().toString();
} catch (TransformerException e) {
e.printStackTrace();
}
return xmlResult;
}

}

ディスパッチ・インスタンスの作成

javax.xml.ws.Serviceインタフェースは、Dispatchインスタンスの作成でファクトリとして機能します。ディスパッチ・インスタンスを作成するには、まずServiceインスタンスを作成する必要があります。その後、Service.createDispatch()メソッドを使用してディスパッチ・インスタンスを作成します。

次のパラメータから1つ以上のパラメータをcreateDispatch()メソッドに渡すことができます。

- ターゲット・サービス・エンドポイントの修飾された名前(QName)またはエンドポイント参照。

- タイプ・パラメータTのクラス。この例では、javax.xml.transform.Sourceフォーマットが使用されます。有効な値は、表19-2を参照してください。

- 使用モード。この例では、メッセージ・ペイロードが指定されます。有効な使用モードは、表19-1を参照してください。

- プロキシで構成するWebサービス機能のリスト。

- メッセージまたはメッセージ・ペイロードのマーシャルまたはアンマーシャルに使用されるJAXBコンテキスト。

Service.createDispatch()メソッドの呼出しに使用できる有効なパラメータの詳細は、javax.xml.ws.Service Javadoc(https://jax-ws.dev.java.net/nonav/2.1.1/docs/api/javax/xml/ws/Service.html)を参照してください。

例:

...
String url_str = System.getProperty("wsdl");
QName serviceName = new QName("http://example.org", "SimpleImplService");
service = Service.create(serviceName);
service.addPort(portQName, SOAPBinding.SOAP11HTTP_BINDING, url_str);
Dispatch<Source> sourceDispatch =
service.createDispatch(portQName, Source.class, Service.Mode.PAYLOAD);
...

前の例では、createDispatch()メソッドは次の3つのパラメータを取ります。

- ターゲット・サービス・エンドポイントの修飾された名前(QName)。

- タイプ・パラメータTのクラス。この例では、javax.xml.transform.Sourceフォーマットが使用されます。有効な値は、表19-2を参照してください。

- 使用モード。この例では、メッセージ・ペイロードが指定されます。有効な使用モードは、表19-1を参照してください。

次の例では、Webサービス機能のリストを渡す方法を示します。具体的には、非同期クライアント・トランスポート機能と非同期クライアント・ハンドラ機能を渡します。これらの機能の詳細は、第4章「Webサービスの非同期呼出し」を参照してください。

...
protected Dispatch createDispatch(boolean isSoap12, Class dateType,
Service.Mode mode, AsyncClientHandlerFeature feature)
throws Exception {
String address = publishEndpoint(isSoap12);
Service service = Service.create(new URL(address + "?wsdl"),
new QName("http://example.org", "AddNumbersService"));
QName portName = new QName("http://example.org", "AddNumbersPort");
AsyncClientTransportFeature transportFeature = new
AsyncClientTransportFeature("http://localhost:8238/clientsoap12/" +
UUID.randomUUID().toString());
Dispatch dispatch = service.createDispatch(portName, dateType, mode,
feature, transportFeature);
return dispatch;
}
...

Webサービス操作の呼出し

Dispatchインスタンスが作成されたら、それを使用してWebサービス操作を呼び出します。Webサービス操作は、同期(一方向または双方向)または非同期(ポーリングまたは非同期ハンドラ)で呼び出すことができます。同期および非同期の呼出し方法の詳細は、javax.xml.ws.Dispatch Javadoc(https://jax-ws.dev.java.net/nonav/2.1.1/docs/api/javax/xml/ws/Dispatch.html)を参照してください。

たとえば、次のコードの抜粋では、XMLメッセージはjavax.xml.transform.stream.StreamSourceオブジェクトとしてカプセル化され、同期invoke()メソッドに渡されています。レスポンスXMLはresult変数でSourceオブジェクトとして返され、XMLに変換されます。メッセージをXMLに戻すために使用されるsourcetoXMLString()メソッドは、例19-3に示しています。

...
private static String request = "<ns1:sayHello xmlns:ns1=\"http://example.org\"><arg0>"+in_str+"</arg0></ns1:sayHello>";
Source result = sourceDispatch.invoke(new StreamSource(new StringReader(request)));
String xmlResult = sourceToXMLString(result);
...

20 XML over HTTPを使用するWebサービスのプログラミング

この章では、XML over HTTPを使用するWebサービスのプログラミング方法について説明します。

この章の内容は以下のとおりです。

- XML over HTTPを使用するWebサービスのプログラミングの概要

- XML over HTTPを使用するWebサービスのプログラミングのガイドライン

- クライアントからWebサービスにアクセスする

- XML over HTTPを使用するWebサービスの保護

XML over HTTPを使用するWebサービスのプログラミングの概要

標準的なSOAP over HTTPの使用例に加えて、XML over HTTP方式の一部のWebサービスでもWebLogic JAX-WSを使用できます。XML over HTTP方式を使用すると、JAX-WSプログラミング・モデルの利便性を活用しながら、単純でRESTfulなWebサービスを構築できます。

注意:

ベスト・プラクティスとしてお薦めする方法は、Jersey JAX-RS RIを使用してRESTfulなWebサービスを開発することです(RESTfulなWebサービスの開発に関する項を参照)。Jersey JAX-RS RIでは、RESTfulなWebサービスを構築するために本番環境として使用できるオープン・ソースのRIが提供され、すべてのHTTPメソッドがサポートされます。

HTTPプロトコルを使用してWebサービス・リソースにアクセスする場合、リソース識別子はリソースのURLであり、このリソースで実行される標準の操作はHTTPの1つのメソッド(GET、PUT、DELETE、POST、またはHEAD)です。

注意:

このJAX-WS実行で、サポートされたHTTPメソッドのセットがGETおよびPOSTに限定されています。DELETE、PUTおよびHEADがサポートされません。これらのメソッドを含むどのHTTP要求も405不可のメソッドというエラー・メッセージが表示され、拒否されます。

PUTおよびDELETEの機能が必須の場合、POSTメソッドで実行される実際のメソッドをトンネリングすることによって目的のアクションを実行できます。これは、オーバーロードPOSTと呼ばれる回避策です。「REST過負荷POST」でのWeb検索は、これを実行するためのいくつかの方法を返します。

javax.xml.ws.Provider<T>インタフェースのinvoke()メソッドを使用してRESTfulに類似したエンドポイントを構築します(http://download.oracle.com/javaee/5/api/javax/xml/ws/Provider.htmlを参照)。Providerインタフェースは、サービス・エンドポイント・インタフェース(SEI)を構築するための動的な代替手段を提供します。

この項の手順では、XML over HTTPを使用してWebサービスを実装するために必要なJWSファイルをプログラミングおよびコンパイルする方法について説明します。この手順では、これらのJWSファイルをゼロから作成する方法を示しています。既存のJWSファイルを更新する場合は、この手順をガイドとして利用してください。

Antベースの開発環境を設定済であり、かつjwsc Antタスクを実行してWebサービスをデプロイするためのターゲットを追加できる、作業用のbuild.xmlファイルがあることが前提となっています。詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』を参照してください。

表20-1 RESTfulなWebサービスのプログラミング手順

#

手順

説明

1

XML over HTTPを使用するWebサービスを実装する、新しいJWSファイルを作成するか、既存のJWSファイルを更新します。

使い慣れたIDEまたはテキスト・エディタを使用します。「XML over HTTPを使用するWebサービスのプログラミングのガイドライン」を参照してください。

2

build.xmlファイルを更新して、JWSファイルをWebサービスにコンパイルするjwsc Antタスクの呼出しを含めます。

例:

<jwsc srcdir="." destdir="output/restEar">
<jws file="NearbyCity.java" type="JAXWS"/>
</jwsc>

詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のjwsc WebLogic WebサービスAntタスクの実行に関する項を参照してください。

3

Antターゲットを実行して、Webサービスを構築します。

例:

prompt> ant build-rest

4

Webサービスを通常どおりデプロイします。

『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebLogic Webサービスのデプロイとアンデプロイに関する項を参照してください。

5

Webサービス・クライアントからWebサービスにアクセスします。

「クライアントからWebサービスにアクセスする」を参照してください。

XML over HTTPを使用するWebサービスのプログラミングのガイドライン

次のサンプルでは、XML over HTTPを使用するWebサービスを実装する簡単なJWSファイルを示します。太字で示されたJavaコードに対応するコーディングのガイドラインについては、サンプルの後の説明を参照してください。

package examples.webservices.jaxws.rest;
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.BindingType;
import javax.xml.ws.Provider;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.http.HTTPBinding;
import javax.xml.ws.http.HTTPException;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.util.StringTokenizer;

@WebServiceProvider(
targetNamespace="http://example.org",
serviceName = "NearbyCityService")
@BindingType(value = HTTPBinding.HTTP_BINDING)

public class NearbyCity implements Provider<Source> {
@Resource(type=Object.class)
protected WebServiceContext wsContext;

public Source invoke(Source source)  {
try {
MessageContext messageContext = wsContext.getMessageContext();

// Obtain the HTTP mehtod of the input request.
javax.servlet.http.HttpServletRequest servletRequest =
(javax.servlet.http.HttpServletRequest)messageContext.get(
MessageContext.SERVLET_REQUEST);
String httpMethod = servletRequest.getMethod();
if (httpMethod.equalsIgnoreCase("GET"));
{

String query =
(String)messageContext.get(MessageContext.QUERY_STRING);
if (query != null && query.contains("lat=") &&
query.contains("long=")) {
return createSource(query);
} else {
System.err.println("Query String = "+query);
throw new HTTPException(404);
}
} catch(Exception e) {
e.printStackTrace();
throw new HTTPException(500);
}
}
} else {
// This operation only supports "GET"
throw new HTTPException405);
}
private Source createSource(String str) throws Exception {
StringTokenizer st = new StringTokenizer(str, "=&/");
String latLong = st.nextToken();
double latitude = Double.parseDouble(st.nextToken());
latLong = st.nextToken();
double longitude = Double.parseDouble(st.nextToken());
City nearby = City.findNearBy(latitude, longitude);
String body = nearby.toXML();
return new StreamSource(new ByteArrayInputStream(body.getBytes()));
}

static class City {
String city;
String state;
double latitude;
double longitude;
City(String city, double lati, double longi, String st) {
this.city = city;
this.state = st;
this.latitude = lati;
this.longitude = longi;
}

double distance(double lati, double longi) {
return Math.sqrt((lati-this.latitude)*(lati-this.latitude) +
(longi-this.longitude)*(longi-this.longitude)) ;
}

static final City[] cities = {
new City("San Francisco",37.7749295,-122.4194155,"CA"),
new City("Columbus",39.9611755,-82.9987942,"OH"),
new City("Indianapolis",39.7683765,-86.1580423,"IN"),
new City("Jacksonville",30.3321838,-81.655651,"FL"),
new City("San Jose",37.3393857,-121.8949555,"CA"),
new City("Detroit",42.331427,-83.0457538,"MI"),
new City("Dallas",32.7830556,-96.8066667,"TX"),
new City("San Diego",32.7153292,-117.1572551,"CA"),
new City("San Antonio",29.4241219,-98.4936282,"TX"),
new City("Phoenix",33.4483771,-112.0740373,"AZ"),
new City("Philadelphia",39.952335,-75.163789,"PA"),
new City("Houston",29.7632836,-95.3632715,"TX"),
new City("Chicago",41.850033,-87.6500523,"IL"),
new City("Los Angeles",34.0522342,-118.2436849,"CA"),
new City("New York",40.7142691,-74.0059729,"NY")};
static City findNearBy(double lati, double longi) {
int n = 0;
for (int i = 1; i < cities.length; i++)  {
if (cities[i].distance(lati, longi) <
cities[n].distance(lati, longi)) {
n = i;
}
}
return cities[n];
}

public String toXML() {
return "<ns:NearbyCity xmlns:ns=\"http://example.org\"><City>"
+this.city+"</City><State>"+ this.state+"</State><Lat>"
+this.latitude +
"</Lat><Lng>"+this.longitude+"</Lng></ns:NearbyCity>";
}
}
}

XML over HTTPを使用するWebサービスを実装するJWSファイルをプログラミングする際には、次のガイドラインに従います。ガイドラインのコード・スニペットは、前述のサンプルでは太字で示されています。

- プロバイダWebサービスを実装するために必要なパッケージをインポートします。

import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.BindingType;
import javax.xml.ws.Provider;

- Provider実装クラスにアノテーションを追加し、HTTPに対するバインディング・タイプを設定します。

@WebServiceProvider(
targetNamespace="http://example.org",
serviceName = "NearbyCityService")
@BindingType(value = HTTPBinding.HTTP_BINDING)

- Providerインタフェースのinvoke()メソッドを実装します。

public class NearbyCity implements Provider<Source> {
@Resource(type=Object.class)
protected WebServiceContext wsContext;

public Source invoke(Source source)  {
...
}

- 処理のためQUERY_STRINGのフィールドで、処理するのにjavax.xml.ws.handler.MessageContextでQUERY_STRINGフィールドを使用したリクエスト文字列を取得します(メッセージURL http://download.oracle.com/javaee/5/api/javax/xml/ws/handler/MessageContext.htmlを参照してください)。その後、問合せ文字列がcreateSource()メソッドに渡され、指定した値に最も近い市、州、緯度、経度が返されます。

String query =
(String)messageContext.get(MessageContext.QUERY_STRING);
.
.
.
return createSource(query);

クライアントからWebサービスにアクセスする

Webサービス・クライアントからWebサービスにアクセスするには、リソースのURIを使用します。例:

URL url = new URL (http://localhost:7001/NearbyCity/NearbyCityService?lat=35&long=-120);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
// Get result
InputStream is = connection.getInputStream();

この例では、緯度(lat)と経度(long)の値を指定して、必要なリソースにアクセスしています。

XML over HTTPを使用するWebサービスの保護

Webアプリケーションの保護に使用するメソッドと同じメソッドを使用して、XML over HTTPを使用するWebサービスを保護することができます。詳細については、『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』のWebアプリケーションの保護のオプションに関する項を参照してください。

21 HTTPセッションを使用したステートフルJAX-WS Webサービスのプログラミング

この章では、Oracleデータベースと対話する、Java API for XML Web Services (JAX-WS)を使用したWebLogic Webサービスの開発方法について説明します。

この章の内容は以下のとおりです。

- ステートフルWebサービスの概要

- サーバーでHTTPセッションにアクセスする

- クライアントでのHTTPセッションの有効化

- セッション状態レプリケーションを使用してクラスタ内のステートフル・サービスを開発する

- JAX-WS RI @ステートフル拡張に関する注意

ステートフルWebサービスの概要

通常、JAX-WS Webサービスはステートレスです。つまり、Webサービス・オブジェクトに設定したどのローカル変数とオブジェクト値も、1つの呼出しから次の呼び出しまで保存されません。1つのクライアントからの順次的な各リクエストも独立、ステートレス・メソッド呼出しとして扱われます。

Webサービスの使用例として、クライアントが呼出しの途中でサービスにデータを保存しておき、その後の呼出しで保存したデータを使用するというものがあります。たとえば、ショッピング・カート・オブジェクトを、addToCart Webメソッドを繰り返し呼び出して追加した後、getCart webメソッドで取得するとします。ステートレスWebサービスでは、addToCartメソッド呼出しの数に関係なく、ショッピング・カート・オブジェクトは常に空となります。しかし、HTTPセッションを使用して複数のWebサービス呼出しにわたって状態を保持すれば、カートの中身を徐々に増やした後、カートをクライアントに戻すことができます。

JAX-WS Webサービスでのステートフル・サポートは、クライアント側、サーバー側ともに最小限のコーディングで有効にできます。

サーバーでHTTPセッションにアクセスする

サーバーでは、すべてのWebサービス呼出しがHttpSessionオブジェクトに関連付けられています。このオブジェクトは、リソース・インジェクションを使用してWebサービス・オブジェクトにバインドされているWebサービス・コンテキストからアクセス可能です。HttpSessionオブジェクトにアクセスしたら、それに任意のステートフル・オブジェクトを「ハング」オフできます。クライアントが次にWebサービスを呼び出すと、Webサービスは同じHttpSessionオブジェクトを見つけて、その中に以前格納したオブジェクトを参照することができます。これでWebサービスはステートフルになりました。

サーバーでの必要な手順は以下のとおりです。

1. Webサービスの冒頭に(Common Annotations for the Java Platform、JSR 250で定義されている)@Resourceを追加します。

2. コンテキストが注入されているWebServiceContext型の変数を追加します。

3. Webサービス・コンテキストを使用してHttpSessionオブジェクトを取得します。

4. setAttributeメソッドを使用してHttpSessionにオブジェクトを保存し、getAttributeを使用して格納されたオブジェクトを取得します。オブジェクトが割り当てる文字列値によって識別されます。

次のスニペットは、その使い方を示します:

例21-1 サーバーでのHTTPセッションへのアクセス

@WebService
public class ShoppingCart {
@Resource    // Step 1
private WebServiceContext wsContext;    // Step 2
public int addToCart(Item item) {
// Find the HttpSession
MessageContext mc = wsContext.getMessageContext();    // Step 3
HttpSession session = ((javax.servlet.http.HttpServletRequest)mc.get(MessageContext.SERVLET_REQUEST)).getSession();
if (session == null)
throw new WebServiceException("No HTTP Session found");
// Get the cart object from the HttpSession (or create a new one)
List<Item> cart = (List<Item>)session.getAttribute("myCart");  // Step 4
if (cart == null)
cart = new ArrayList<Item>();
// Add the item to the cart (note that Item is a class defined
// in the WSDL)
cart.add(item);
// Save the updated cart in the HTTPSession (since we use the same
// "myCart" name, the old cart object will be replaced)
session.setAttribute("myCart", cart);
// return the number of items in the stateful cart
return cart.size();
}
}

クライアントでのHTTPセッションの有効化

クライアント側コードはとても簡単です。必要なのは、リクエスト・コンテキストにSESSION_MAINTAIN_PROPERTYを設定することのみです。これにより、Webサービスから受信したHTTP Cookieを戻すようクライアントに指示します。Cookieには、サーバーがWebサービス呼出しを正しいHttpSessionと対応させるためのセッションIDが含まれており、これによって任意の保存済ステートフル・オブジェクトへのアクセスが可能になります。

例21-2 クライアントのHTTPセッションの有効化

ShoppingCart proxy = new CartService().getCartPort();
((BindingProvider)proxy).getRequestContext().put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true);
// Create a new Item object with a part number of '123456' and an item
// count of 4.
Item item = new Item('123456', 4);
// After first call, we'll print '1' (the return value is the number of objects
// in the Cart object)
System.out.println(proxy.addToCart(item));
// After the second call, we'll print '2', since we've added another
// Item to the stateful, saved Cart object.
System.out.println(proxy.addToCart(item));

セッション状態レプリケーションを使用してクラスタ内のステートフル・サービスを開発する

高可用性環境では、1つのJAX-WS Webサービスがクラスタ内の複数のサーバー・インスタンスにレプリケートされる場合があります。このような環境でステートフルJAX-WS Webサービスをサポートするには、WebLogic Server HTTPセッション状態レプリケーション機能を使用します。詳細は、『Oracle WebLogic Serverクラスタの使用』のHTTPセッション状態レプリケーションに関する項を参照してください。

セッション状態レプリケーションを使用してクラスタ化された環境を設定するには、様々な技術要件および構成要件(サポートされているサーバーやロード・バランサなど)があります。JAX-WSプログラミングの観点から、唯一の新しい考慮事項は、(例21-1に示されているように)HttpSession.setAttributeメソッドを使用してHttpSessionに格納するオブジェクトは、シリアライズ可能であることが必要な点です。シリアライズ可能であると、クラスタ内のレプリケートされたすべてのWebインスタンス上のWebサービスに対してそれらのステートフル・オブジェクトが使用可能になり、JAX-WSステートフルWebサービスでロード・バランシングとフェイルオーバーの両方の機能を使用できるようになります。

JAX-WS RI @ステートフル拡張に関する注意

JAX-WS 2.1 Reference Implementation (RI)には、@Statefulアノテーションを使用してステートフルJAX-WS Webサービスの異なるモデルをサポートするベンダー拡張があります。その実装は、状態を特定のインスタンスに固定するもので、スケーラビリティやフォルト・トレランスを目的としていません。WebLogic Server JAX-WS Webサービスでは、この機能はサポートされません。

A Webサービスの信頼性のあるメッセージングと接続作成のためのあらかじめパッケージ化されたWS-Policyファイル

この付録では、あらかじめパッケージ化されたWS-Policyファイルの概要を説明します。WS-Policyファイルは、Java API for XML Web Services(JAX-WS)を使用したWebLogic Webサービスで、信頼性のあるメッセージング、接続作成、またはこの両方の機能をサポートします。

これらのあらかじめパッケージ化されたファイルを変更することはできません。これらの値がニーズに合ない場合は、独自のWS-Policyファイルを作成する必要があります。詳細は、次の内容を参照してください。

- Webサービスの信頼性のあるメッセージングのWS-Policyファイルの作成

- Webサービスの接続作成WS-Policyファイルの作成(オプション)

信頼性のあるメッセージングおよび接続作成ポリシー・アサーションの詳細は、次を参照してください。

- 『Oracle WebLogic Server WebLogic Webサービス・リファレンス』のWebサービスの信頼性のあるメッセージングのポリシー・アサーションのリファレンスに関する項

- 『Oracle WebLogic Server WebLogic Webサービス・リファレンス』のWebサービスの接続作成ポリシー・アサーションのリファレンスに関する項

次の表に、あらかじめパッケージ化されたWS-Policyファイルをまとめます。この表は、WS-Policyファイルをメソッド・レベルでアタッチできるかどうかも指定します。この列の値が「No」の場合、WS-Policyファイルをクラス・レベルでのみアタッチできます。

表A-1 信頼性のあるメッセージングをサポートする、あらかじめパッケージ化されているWS-Policyファイル

あらかじめパッケージ化されているWS-Policyファイル

説明

メソッド・レベルのアタッチ

DefaultReliability1.2.xml

配信保証に関するポリシー・アサーションを指定します。Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrmp/200702のWS Reliable Messaging Policy Assertion 1.2が基になっています。「DefaultReliability1.2.xml(WS-Policyファイル)」を参照してください。

はい

DefaultReliability1.1.xml

サービス品質に関するポリシー・アサーションを指定します。Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrmp/200702/wsrmp-1.1-spec-os-01.htmlのWS Reliable Messaging Policy Assertion 1.1が基になっています。「DefaultReliability1.1.xml (WS-Policyファイル)」を参照してください。

はい

DefaultRelibility.xml

非推奨。Webサービスの信頼性のあるメッセージングのアサーションは、WS Reliable Messaging Policy Assertion Version 1.0(http://schemas.xmlsoap.org/ws/2005/02/rm/WS-RMPolicy.pdf)に基づいています。このリリースでは、信頼性のあるメッセージングのポリシー・アサーションの多くが、JWSアノテーションまたは構成を通じて管理されます。

信頼性のあるメッセージングのポリシー・アサーションに一般的な値(非アクティブ・タイムアウト10分、確認応答の間隔200ミリ秒、基本的な再送信間隔3秒など)を指定します。「DefaultReliability.xml WS-Policyファイル(WS-Policy)[非推奨]」を参照してください。

はい

LongRunningReliability.xml

非推奨。長期実行プロセスに関して、Webサービスの信頼性のあるメッセージングのアサーションは、WS Reliable Messaging Policy Assertion Version 1.0に基づいています。このリリースでは、信頼性のあるメッセージングのポリシー・アサーションの多くが、JWSアノテーションまたは構成を通じて管理されます。

1つ前に示した、信頼性のあるメッセージングのデフォルトWS-Policyファイルとほぼ同じですが、アクティビティのタイムアウト間隔に、より大きな値(24時間)を指定する点が異なります。「LongRunningReliability.xml WS-Policyファイル(WS-Policy)[非推奨]」を参照してください。

はい

Mc1.1.xml

Webサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。WS-Policy 1.5プロトコルが使用されます。「Mc1.1.xml(WS-Policyファイル)」を参照してください。

いいえ

Mc.xml

Webサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。WS-Policy 1.2プロトコルが使用されます。「Mc.xml(WS-Policyファイル)」を参照してください。

いいえ

Reliability1.2_ExactlyOnce_WithMC1.1.xml

サービス品質に関するポリシー・アサーションを指定します。Webサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。「Reliability1.2_ExactlyOnce_WithMC1.1.xml(WS-Policyファイル)」を参照してください。

いいえ

Reliability1.2_SequenceSTRSecurity

信頼性のあるシーケンスでメッセージを保護するために、CreateSequenceメッセージで参照されるwsse:SecurityTokenReferenceをランタイムが使用するように指定します。Webサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrmp/200702のWS Reliable Messaging Policy Assertion 1.2が基になっています。「Reliability1.2_SequenceTransportSecurity.xml(WS-Policyファイル)」を参照してください。

いいえ

Reliability1.1_SequenceSTRSecurity

Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrmp/200702/wsrmp-1.1-spec-os-01.htmlのWS Reliable Messaging Policy Assertion 1.1が基になっています。「Reliability1.1_SequenceTransportSecurity.xml(WS-Policyファイル)」を参照してください。

はい

Reliability1.2_SequenceTransportSecurity

トランスポート・レベルのセキュリティとサービス品質に関連するポリシー・アサーションを指定します。Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrmp/200702のWS Reliable Messaging Policy Assertion 1.2が基になっています。「Reliability1.2_SequenceTransportSecurity.xml(WS-Policyファイル)」を参照してください。

はい

Reliability1.1_SequenceTransportSecurity

トランスポート・レベルのセキュリティとサービス品質に関連するポリシー・アサーションを指定します。Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrmp/200702/wsrmp-1.1-spec-os-01.htmlのWS Reliable Messaging Policy Assertion 1.1が基になっています。「Reliability1.1_SequenceTransportSecurity.xml(WS-Policyファイル)」を参照してください。

はい

Reliability1.0_1.2.xml

1.2と1.0のWS-Reliableメッセージング・ポリシー・アサーションを結合します。1.2バージョンのポリシー・アサーションはWebサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。このサンプルは、適切なポリシーの選択に基づいて実行時に適用されるポリシー・アサーションを決定します。「Reliability1.0_1.2.xml(WS-Policyファイル)」を参照してください。

いいえ

Reliability1.0_1.1.xml

1.1と1.0のWS Reliable Messagingポリシー・アサーションを結合します。「Reliability1.0_1.1.xml(WS-Policy.xmlファイル)」を参照してください。

はい

DefaultReliability1.2.xml(WS-Policyファイル)

DefaultRealiability1.2.xml WS-Policyファイルは、配信保証に関するポリシー・アサーションを指定します。Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrm/200702/wsrm-1.2-spec-os.htmlのWS Reliable Messaging Policy Assertion 1.2が基になっています。

<?xml version="1.0" encoding="UTF-8"?>
<wsp15:Policy xmlns:wsp15="http://www.w3.org/ns/ws-policy">
<wsp15:All>
<wsrmp:RMAssertion
xmlns:wsrmp="http://docs.oasis-open.org/ws-rx/wsrmp/200702">
<wsrmp:DeliveryAssurance>
<wsp15:Policy>
<wsrmp:ExactlyOnce/>
<wsrmp:InOrder/>
</wsp15:Policy>
</wsrmp:DeliveryAssurance>
</wsrmp:RMAssertion>
</wsp15:All>
</wsp15:Policy>

DefaultReliability1.1.xml(WS-Policyファイル)

DefaultRealiability1.1.xml WS-Policyファイルは、サービス品質に関するポリシー・アサーションを指定します。Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrmp/200702/wsrmp-1.1-spec-os-01.htmlのWS Reliable Messaging Policy Assertion 1.1が基になっています。

<?xml version="1.0"?>

<wsp:Policy
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
>
<wsrmp:RMAssertion
xmlns:wsrmp="http://docs.oasis-open.org/ws-rx/wsrmp/200702"
>
<wsrmp:DeliveryAssurance>
<wsp:Policy>
<wsrmp:ExactlyOnce />
</wsp:Policy>
</wsrmp:DeliveryAssurance>
</wsrmp:RMAssertion>
</wsp:Policy>

DefaultReliability.xml WS-Policyファイル(WS-Policy)[非推奨]

このWS-Policyファイルは非推奨となっています。Webサービスの信頼性のあるメッセージングのアサーションは、WS Reliable Messaging Policy Assertion Version 1.0(http://schemas.xmlsoap.org/ws/2005/02/rm/policy/)に基づいています。現在のリリースでは、信頼性のあるメッセージングのポリシー・アサーションの多くが、JWSアノテーションまたは構成を通じて管理されます。

DefaultReliability.xml WS-Policyファイルは、信頼性のあるメッセージングのポリシーのアサーションに一般的な値(非アクティブ・タイムアウト10分、確認応答の間隔200ミリ秒、基本的な再送信間隔3秒など)を指定します。

<?xml version="1.0"?>

<wsp:Policy
xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm/policy"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:beapolicy="http://www.bea.com/wsrm/policy"
>

<wsrm:RMAssertion >
<wsrm:InactivityTimeout Milliseconds="600000" />
<wsrm:BaseRetransmissionInterval Milliseconds="3000" />
<wsrm:ExponentialBackoff />
<wsrm:AcknowledgementInterval Milliseconds="200" />
<beapolicy:Expires Expires="P1D" optional="true"/>
</wsrm:RMAssertion>
</wsp:Policy>

LongRunningReliability.xml WS-Policyファイル(WS-Policy)[非推奨]

このWS-Policyファイルは非推奨となっています。Webサービスの信頼性のあるメッセージングのアサーションは、WS Reliable Messaging Policy Assertion Version 1.0(http://schemas.xmlsoap.org/ws/2005/02/rm/policy/)に基づいています。現在のリリースでは、信頼性のあるメッセージングのポリシー・アサーションの多くが、JWSアノテーションまたは構成を通じて管理されます。

LongRunningRelibility.xml WS-Policyファイルは、DefaultReliability.xml WS-Policyファイルと同じような値を指定しますが、指定するアクティビティのタイムアウト間隔がより長い(24時間)点が異なります。「LongRunningReliability.xml WS-Policyファイル(WS-Policy)[非推奨]」を参照してください。

<?xml version="1.0"?>

<wsp:Policy
xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm/policy"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:beapolicy="http://www.bea.com/wsrm/policy"
>
<wsrm:RMAssertion >
<wsrm:InactivityTimeout Milliseconds="86400000" />
<wsrm:BaseRetransmissionInterval Milliseconds="3000" />
<wsrm:ExponentialBackoff />
<wsrm:AcknowledgementInterval Milliseconds="200" />
<beapolicy:Expires Expires="P1M" optional="true"/>
</wsrm:RMAssertion>
</wsp:Policy>

Mc1.1.xml(WS-Policyファイル)

Mc1.1.xml WS-Policyファイルは、Webサービスにおける接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を設定します。この場合、WS-Policy 1.5プロトコルが使用されます。アサーションは、http://docs.oasis-open.org/ws-rx/wsmc/200702/wsmc-1.1-spec-os.htmlに定義されている接続作成ポリシー・アサーションに基づいています。

<?xml version="1.0"?>
<wsp15:Policy
xmlns:wsp15="http://www.w3.org/ns/ws-policy"
xmlns:wsmc="http://docs.oasis-open.org/ws-rx/wsmc/200702">
<wsmc:MCSupported wsp15:Optional="true" />
</wsp15:Policy>

Mc.xml(WS-Policyファイル)

Mc.xml WS-Policyファイルは、Webサービスにおける接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を設定します。アサーションは、http://docs.oasis-open.org/ws-rx/wsmc/200702/wsmc-1.1-spec-os.htmlに定義されている接続作成ポリシー・アサーションに基づいています。

<?xml version="1.0"?>
<wsp:Policy
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsmc="http://docs.oasis-open.org/ws-rx/wsmc/200702">
<wsmc:MCSupported wsp:Optional="true" />
</wsp:Policy>

Reliability1.2_ExactlyOnce_WithMC1.1.xml(WS-Policyファイル)

Reliability1.2_ExactlyOnce_WithMC1.1.xml WS-Policyファイルは、サービス品質に関するポリシー・アサーションを指定します。Webサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。

アサーションは、次の仕様に基づいています。

- Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrm/200702/wsrm-1.2-spec-os.htmlのWS Reliable Messaging Policy Assertion 1.2に基づいています。

- 接続作成アサーションは、http://docs.oasis-open.org/ws-rx/wsmc/200702/wsmc-1.1-spec-os.htmlに定義されている接続作成ポリシー・アサーションに基づいています。

<?xml version="1.0" encoding="UTF-8" ?>
<wsp15:Policy xmlns:wsp15="http://www.w3.org/ns/ws-policy">
<wsp15:All>
<wsrmp:RMAssertion
xmlns:wsrmp="http://docs.oasis-open.org/ws-rx/wsrmp/200702">
<wsrmp:DeliveryAssurance>
<wsp15:Policy>
<wsrmp:ExactlyOnce />
</wsp15:Policy>
</wsrmp:DeliveryAssurance>
</wsrmp:RMAssertion>
<wsmc:MCSupported
xmlns:wsmc="http://docs.oasis-open.org/ws-rx/wsmc/200702"
wsp15:Optional="true" />
</wsp15:All>
</wsp15:Policy>

Reliability1.2_SequenceSTR.xml(WS-Policyファイル)

Reliability1.2_SequenceSTR.xmlファイルは、信頼性のあるシーケンスでメッセージを保護するために、CreateSequenceメッセージで参照されるwsse:SecurityTokenReferenceをランタイムが使用するように指定します。Webサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。

アサーションは、次の仕様に基づいています。

- Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrm/200702/wsrm-1.2-spec-os.htmlのWS Reliable Messaging Policy Assertion 1.2に基づいています。

- 接続作成アサーションは、http://docs.oasis-open.org/ws-rx/wsmc/200702/wsmc-1.1-spec-os.htmlに定義されている接続作成ポリシー・アサーションに基づいています。

<?xml version="1.0" encoding="UTF-8"?>
<wsp15:Policy xmlns:wsp15="http://www.w3.org/ns/ws-policy">
<wsp15:All>
<wsrmp:RMAssertion
xmlns:wsrmp="http://docs.oasis-open.org/ws-rx/wsrmp/200702">
<wsrmp:SequenceSTR/>
<wsrmp:DeliveryAssurance>
<wsp15:Policy>
<wsrmp:ExactlyOnce/>
</wsp15:Policy>
</wsrmp:DeliveryAssurance>
</wsrmp:RMAssertion>
<wsmc:MCSupported
xmlns:wsmc="http://docs.oasis-open.org/ws-rx/wsmc/200702"
wsp15:Optional="true"/>
</wsp15:All>
</wsp15:Policy>

Reliability1.1_SequenceSTR.xml(WS-Policyファイル)

Reliability1.1_SequenceSTR.xmlファイルは、信頼性のあるシーケンスでメッセージを保護するために、CreateSequenceメッセージで参照されるwsse:SecurityTokenReferenceをランタイムが使用するように指定します。Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrmp/200702/wsrmp-1.1-spec-os-01.htmlのWS Reliable Messaging Policy Assertion 1.1が基になっています。

<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsrmp:RMAssertion
xmlns:wsrmp="http://docs.oasis-open.org/ws-rx/wsrmp/200702">
<wsrmp:SequenceSTR/>
<wsrmp:DeliveryAssurance>
<wsp:Policy>
<wsrmp:ExactlyOnce/>
</wsp:Policy>
</wsrmp:DeliveryAssurance>
</wsrmp:RMAssertion>
</wsp:Policy>

Reliability1.2_SequenceTransportSecurity.xml(WS-Policyファイル)

Reliability1.2_SequenceTransportSecurity.xmlファイルは、トランスポート・レベルのセキュリティおよびサービス品質に関するポリシー・アサーションを指定します。Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrm/200702/wsrm-1.2-spec-os.htmlのWS Reliable Messaging Policy Assertion 1.2が基になっています。

<?xml version="1.0" encoding="UTF-8"?>
<wsp15:Policy xmlns:wsp15="http://www.w3.org/ns/ws-policy">
<wsp15:All>
<wsrmp:RMAssertion
xmlns:wsrmp="http://docs.oasis-open.org/ws-rx/wsrmp/200702">
<wsrmp:SequenceTransportSecurity/>
<wsrmp:DeliveryAssurance>
<wsp15:Policy>
<wsrmp:ExactlyOnce/>
</wsp15:Policy>
</wsrmp:DeliveryAssurance>
</wsrmp:RMAssertion>
</wsp15:All>
</wsp15:Policy>

Reliability1.1_SequenceTransportSecurity.xml(WS-Policyファイル)

Reliability1.1_SequenceTransportSecurity.xmlファイルは、トランスポート・レベルのセキュリティおよびサービス品質に関するポリシー・アサーションを指定します。Webサービスの信頼性のあるメッセージング・アサーションは、http://docs.oasis-open.org/ws-rx/wsrmp/200702/wsrmp-1.1-spec-os-01.htmlのWS Reliable Messaging Policy Assertion 1.1が基になっています。

<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsrmp:RMAssertion
xmlns:wsrmp="http://docs.oasis-open.org/ws-rx/wsrmp/200702">
<wsrmp:SequenceTransportSecurity/>
<wsrmp:DeliveryAssurance>
<wsp:Policy>
<wsrmp:ExactlyOnce/>
</wsp:Policy>
</wsrmp:DeliveryAssurance>
</wsrmp:RMAssertion>
</wsp:Policy>

Reliability1.0_1.2.xml(WS-Policyファイル)

Reliability1.0_1.2.xml WS-Policyファイルは、1.2および1.0のWS-信頼性のあるメッセージングのポリシー・アサーションを結合します。

このサンプルは、適切なポリシーの選択に基づいて実行時に適用されるポリシー・アサーションを決定します。適切なポリシーの選択の詳細は、「複数のポリシー選択肢の使用」を参照してください。

<?xml version="1.0" encoding="UTF-8"?>
<wsp15:Policy xmlns:wsp15="http://www.w3.org/ns/ws-policy">
<wsp15:ExactlyOne>
<wsp15:All>
<wsrmp:RMAssertion
xmlns:wsrmp="http://docs.oasis-open.org/ws-rx/wsrmp/200702">
<wsrmp:DeliveryAssurance>
<wsp15:Policy>
<wsrmp:ExactlyOnce/>
</wsp15:Policy>
</wsrmp:DeliveryAssurance>
</wsrmp:RMAssertion>
<wsmc:MCSupported
xmlns:wsmc="http://docs.oasis-open.org/ws-rx/wsmc/200702"
wsp15:Optional="true"/>
</wsp15:All>
<wsp15:All>
<wsrmp10:RMAssertion
xmlns:wsrmp10="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
<wsrmp10:InactivityTimeout Milliseconds="600000"/>
<wsrmp10:BaseRetransmissionInterval Milliseconds="3000"/>
<wsrmp10:ExponentialBackoff/>
<wsrmp10:AcknowledgementInterval Milliseconds="200"/>
</wsrmp10:RMAssertion>
</wsp15:All>
</wsp15:ExactlyOne>
</wsp15:Policy>

Reliability1.0_1.1.xml(WS-Policy.xmlファイル)

Reliability1.0_1.1.xml WS-Policyファイルは、1.1および1.0のWS-信頼性のあるメッセージングのポリシー・アサーションを結合します。このサンプルは、適切なポリシーの選択に基づいて実行時に適用されるポリシー・アサーションを決定します。適切なポリシーの選択の詳細は、「複数のポリシー選択肢の使用」を参照してください。

注意:

1.0のWebサービスの信頼性のあるメッセージング・アサーションには、接頭辞としてwsrmp10が付加されます。

<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsp:ExactlyOne>
<wsp:All>
<wsrmp:RMAssertion
xmlns:wsrmp="http://docs.oasis-open.org/ws-rx/wsrmp/200702">
<wsrmp:DeliveryAssurance>
<wsp:Policy>
<wsrmp:ExactlyOnce/>
</wsp:Policy>
</wsrmp:DeliveryAssurance>
</wsrmp:RMAssertion>
</wsp:All>
<wsp:All>
<wsrmp10:RMAssertion
xmlns:wsrmp10="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
<wsrmp10:InactivityTimeout Milliseconds="600000"/>
<wsrmp10:BaseRetransmissionInterval Milliseconds="3000"/>
<wsrmp10:ExponentialBackoff/>
<wsrmp10:AcknowledgementInterval Milliseconds="200"/>
</wsrmp10:RMAssertion>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>

B 信頼性のあるメッセージングのバッチ化のためのクライアント・ラッパー・クラスの例

この付録では、Java API for XML Web Services(JAX-WS)を使用したWebLogic Webサービスで、信頼性のあるメッセージングのバッチ処理に使用できるクライアント・ラッパー・クラスの例を示します。

信頼性のあるメッセージングのバッチ化の詳細は、「ビジネス作業単位へのメッセージのグループ化(バッチ化)」を参照してください。

注意:

このクライアント・ラッパー・クラスはサンプル・コードです。正式にサポートされている製品クラスではありません。

例B-1 信頼性のあるメッセージングのバッチ化のためのクライアント・ラッパー・クラスの例

package example.servlet;

import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Date;
import java.util.SortedSet;
import java.util.Timer;
import java.util.TimerTask;

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
import javax.xml.ws.BindingProvider;

import weblogic.wsee.jaxws.JAXWSProperties;
import weblogic.wsee.jaxws.spi.ClientInstance;
import weblogic.wsee.reliability.MessageRange;
import weblogic.wsee.reliability2.api.WsrmClient;
import weblogic.wsee.reliability2.api.WsrmClientFactory;
import weblogic.wsee.reliability2.property.WsrmInvocationPropertyBag;
import weblogic.wsee.reliability2.tube.WsrmClientImpl;

/**
* Example wrapper class to batch reliable requests into fixed size 'batches'
* that can be sent using a single RM sequence. This class allows a client to
* send requests that have no natural common grouping or
* 'business unit of work' and not pay the costs associated with creating and
* terminating an RM sequence for every message.
* NOTE: This class is an *example* of how batching might be performed. To do
*       batching correctly, you should consider error recovery and how to
*       report sequence errors (reported via ReliabilityErrorListener) back
*       to the clients that made the original requests.
* <p>
* If your Web service client code knows of some natural business-oriented
* grouping of requests (called a 'business unit of work'), it should make the
* RM subsystem aware of this unit of work by using the
* WsrmClient.setFinalMessage() method to demarcate the end of a unit (just
* before sending the actual final request via an invocation on
* the client instance). In some cases, notably when the client code represents
* an intermediary in the processing of messages, the client code may not be
* aware of any natural unit of work. In the past, if no business unit of work
* could be determined, clients often just created the client instance, sent the
* single current message they had, and then allowed the sequence to terminate.
* This is functionally workable, but very inefficient. These clients pay the
* cost of an RM sequence handshake and termination for every message they send.
* The BatchingRmClientWrapper class can be used to introduce an artificial
* unit of work (a batch) when no natural business unit of work is available.
* <p>
* Each instance of BatchingRmClientWrapper is a wrapper instance around a
* client instance (port or Dispatch instance). This wrapper can be used to
* obtain a Proxy instance that can be used in place of the original client
* instance. This allows this class to perform batching operations completely
* invisibly from the perspective of the client code.
* <p>
* This class is used for batching reliable requests into
* batches of a given max size that will survive for a given maximum
* duration. If a batch fills up or times out, it is ended, causing the
* RM sequence it represents to be ended/terminated. The timeout ensures that
* if the flow of incoming requests stops the batch/sequence will still
* end in a timely manner.
*/
public class BatchingRmClientWrapper<T>
implements InvocationHandler {

private Class<T> _clazz;
private int _batchSize;
private long _maxBatchLifetimeMillis;
private T _clientInstance;
private PrintWriter _out;
private WsrmClient _rmClient;
private int _numInCurrentBatch;
private int _batchNum;
private Timer _timer;
private boolean _closed;
private boolean _proxyCreated;

/**
* Create a wrapper instance for batching reliable requests into
* batches of the given max size that will survive for the given maximum
* duration. If a batch fills up or times out, it is ended, causing the
* RM sequence it represents to be ended/terminated.
* @param clientInstance The client instance that acts as the source object
*        for the batching proxy created by the createProxy() method. This
*        is the port/Dispatch instance returned from the call to
*        getPort/createDispatch. The BatchingRmClientWrapper will take over
*        responsibility for managing the interaction with and cleanup of
*        the client instance via the proxy created from createProxy.
* @param clazz of the proxy instance we'll be creating in createProxy.
*        This should be the class of the port/Dispatch instance you would
*        use to invoke operations on the service. BatchingRmClientWrapper will
*        create (via createProxy) a proxy of the given type that can be
*        used in place of the original client instance.
* @param batchSize Max number of requests to put into a batch. If the
*        max number of requests are sent for a given batch, that batch is
*        ended (ending/terminating the sequence it represents) and a new
*        batch is started.
* @param maxBatchLifetime A duration value (in the lexical form supported
*        by java.util.Duration, e.g. PT30S for 30 seconds) representing
*        the maximum time a batch should exist. If the batch exists longer
*        than this time, it is ended and a new batch is begun.
* @param out A print stream that can be used to print diagnostic and
*        status messages.
*/
public BatchingRmClientWrapper(T clientInstance, Class<T> clazz,
int batchSize, String maxBatchLifetime,
PrintStream out) {
_clazz = clazz;
_batchSize = batchSize;
try {
if (maxBatchLifetime == null) {
maxBatchLifetime = "PT5M";
}
Duration duration =
DatatypeFactory.newInstance().newDuration(maxBatchLifetime);
_maxBatchLifetimeMillis = duration.getTimeInMillis(new Date());
} catch (Exception e) {
throw new RuntimeException(e.toString(), e);
}
_clientInstance = clientInstance;
_out = new PrintWriter(out, true);
_rmClient = WsrmClientFactory.getWsrmClientFromPort(_clientInstance);
_closed = false;
_proxyCreated = false;
_timer = new Timer(true);
_timer.schedule(new TimerTask() {
@Override
public void run() {
terminateOrEndBatch();
}
}, _maxBatchLifetimeMillis);
}

/**
* Creates the dynamic proxy that should be used in place of the client
* instance used to create this BatchingRmClientWrapper instance. This method
* should be called only once per BatchingRmClientWrapper.
*/
public T createProxy() {
if (_proxyCreated) {
throw new IllegalStateException("Already created the proxy for this BatchingRmClientWrapper
instance which wraps the client instance: " + _clientInstance);
}
_proxyCreated = true;
return (T) Proxy.newProxyInstance(getClass().getClassLoader(),
new Class[] {
_clazz,
BindingProvider.class,
java.io.Closeable.class
}, this);
}

private void terminateOrEndBatch() {
synchronized(_clientInstance) {
if (_rmClient.getSequenceId() != null) {
if (terminateBatchAllowed()) {
_out.println("Terminating batch " + _batchNum + " sequence (" + _
rmClient.getSequenceId() + ") for " + _clientInstance);
try {
_rmClient.terminateSequence();
} catch (Exception e) {
e.printStackTrace(_out);
}
} else {
_out.println("Batch " + _batchNum + " sequence (" + _rmClient.getSequenceId() + ")
for " + _clientInstance + " timed out but has outstanding requests to send and
cannot be terminated now");
}
}
endBatch();
}
}

/**
* Check to see if we have acks for all requests sent. If so,
* we can terminate.
*/
private boolean terminateBatchAllowed() {
try {
synchronized(_clientInstance) {
if (_rmClient.getSequenceId() != null) {
long maxMsgNum = _rmClient.getMostRecentMessageNumber();
if (maxMsgNum < 1) {
// No messages sent, go ahead and terminate.
return true;
}
SortedSet<MessageRange> ranges = _rmClient.getAckRanges();
long maxAck = -1;
boolean hasGaps = false;
long lastRangeUpper = -1;
for (MessageRange range: ranges) {
if (lastRangeUpper > 0) {
if (range.lowerBounds != lastRangeUpper + 1) {
hasGaps = true;
}
} else {
lastRangeUpper = range.upperBounds;
}
maxAck = range.upperBounds;
}
return !(hasGaps || maxAck < maxMsgNum);
}
}
} catch (Exception e) {
e.printStackTrace(_out);
}
return true;
}

private void endBatch() {
synchronized(_clientInstance) {
if (_numInCurrentBatch > 0) {
_out.println("Ending batch " + _batchNum + " sequence (" + _rmClient.getSequenceId() + ")
for " + _clientInstance + "...");
}
/**
* _rmClient.reset() resets a WsrmClient instance (and the client instance it represents)
* so it can track a new WS-RM sequence for the next invoke on the client
* instance. This method effectively *disconnects* the RM sequence from the
* client instance and lets them continue/complete separately.
*/
_rmClient.reset();
_numInCurrentBatch = 0;
if (!_closed) {
_timer.schedule(new TimerTask() {
@Override
public void run() {
terminateOrEndBatch();
}
}, _maxBatchLifetimeMillis);
}
}
}

public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
boolean operationInvoke = method.getDeclaringClass() == _clazz;
boolean closeableInvoke = method.getDeclaringClass() ==
java.io.Closeable.class;
boolean endOfBatch = false;
if (operationInvoke) {
synchronized(_clientInstance) {
// Check our batch size
if (_numInCurrentBatch == 0) {
_batchNum++;
}
endOfBatch = _numInCurrentBatch >= _batchSize - 1;
if (endOfBatch) {
_rmClient.setFinalMessage();
}
_out.println("Making " + (endOfBatch ? "final " : "") + "invoke " +
(_numInCurrentBatch+1) + " of batch " + _batchNum + " sequence (" + _
rmClient.getSequenceId() + ") with operation: " + method.getName());
}
} else if (closeableInvoke && method.getName().equals("close")) {
synchronized(_clientInstance) {
// Make sure we don't try to schedule the timer anymore
_closed = true;
_timer.cancel();
}
}
Object ret = method.invoke(_clientInstance, args);
if (operationInvoke) {
synchronized(_clientInstance) {
_numInCurrentBatch++;
if (endOfBatch) {
endBatch();
}
}
}
return ret;
}
}

Copyright © 2007, 2012, Oracle and/or its affiliates. All rights reserved.