ヘッダーをスキップ
Oracle XML Developer's Kitプログラマーズ・ガイド
10gリリース3(10.1.3)
B28611-01
  目次
目次
索引
索引

戻る
戻る
次へ
次へ
 

11 XDKおよびSOAPの使用

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

SOAPの概要

Webサービスという用語は、Web上でエンティティによって使用可能になる機能の説明に使用されます。これはXML標準を使用するアプリケーションであり、Webを介して公開、検索および実行されます。

Simple Object Access Protocol(SOAP)は、リクエストおよびレスポンスをインターネット経由で送受信するための軽量プロトコルです。このプロトコルはXML、およびHTTPなどの単純な転送プロトコルに基づくため、ファイアウォールによってブロックされず、非常に簡単に使用できます。SOAPはオペレーティング・システム、実装言語および単一のオブジェクト・モデルに依存しません。

SOAPはリモート・プロシージャ・コールをサポートします。SOAPのメッセージは次の3種類のみです。

SOAPメッセージは次の部分で構成されています。

SOAP 1.1仕様はWorld Wide Web Consortium(W3C)ノートです。W3C XMLプロトコル・ワーキング・グループは、SOAP 1.1にかわる標準を作成するために結成されました。オラクル社はこのグループのメンバーです。標準はSOAP 1.2になる予定です。

SOAPサービスのリモート・プロシージャ・コール(RPC)・リクエストおよびレスポンスの手順は、次のとおりです。

  1. SOAPクライアントが、エディタまたはOracle SOAPクライアントAPIを使用して、準拠するXML文書にサービスへのリクエストを書き込みます。

  2. SOAPクライアントは、サービスへのリクエストが書き込まれた文書をWebサーバーでサーブレットとして実行中のSOAPリクエスト・ハンドラに送信します。

  3. Webサーバーはリクエストされたサービスを提供しながら、そのメッセージをサービス・リクエストとして適切なサーバー側アプリケーションにディスパッチします。

  4. サポートされる部分がメッセージに含まれることを、アプリケーションで確認する必要があります。サービスからのレスポンスは、SOAPリクエスト・ハンドラ・サーブレットに戻された後、SOAPペイロード形式を使用してコール側に戻されます。

UDDIおよびWSDLの概要

Universal Description, Discovery and Integration(UDDI)仕様は、XMLを使用してサービスの記述、ビジネスの検出およびインターネット上のビジネス・サービスの統合を行う、プラットフォーム非依存フレームワークを提供します。UDDIビジネス・レジストリは、企業を登録する公共データベースであり、次の3つのセクションからなるXMLファイルです。

Webサービス記述言語(WSDL)は、Webサービスのインタフェース、プロトコル・バインドおよびデプロイの詳細を記述するための汎用XML言語です。WSDLには、抽象インタフェースや任意のネットワーク・サービスを記述する方法があります。WSDLサービスはUDDIレジストリに登録されるか、または埋め込まれます。

次に、Webサービスで使用するプロトコル・スタックの概要を示します。

Oracle SOAPの概要

Oracle SOAPは、Simple Object Access Protocolを実装しています。これはApache Software Foundationで開発されたSOAPオープン・ソース実装に基づくものです。

Oracle SOAPの機能

GetLastTradePrice SOAPリクエストをStockQuoteサービスに送信する例について考えてみます。このリクエストは企業の銘柄記号を示す文字列パラメータを取り、SOAPレスポンスでfloat型を戻します。XML文書がSOAPメッセージです。SOAPのenvelope要素は、XML文書の最上位要素です。XML名前空間を使用して、SOAP識別子とアプリケーション固有の識別子を区別します。次の例では転送プロトコルとしてHTTPを使用します。SOAPでXMLペイロード形式を決定する規則は、このペイロードがHTTPで転送されるということには関係ありません。次に、HTTPリクエストに埋め込まれたSOAPリクエスト・メッセージを示します。

POST /StockQuote HTTP/1.1
Host: www.stockquoteserver.com
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
SOAPAction: "Some-URI"
<SOAP-ENV:Envelope  xmlns:SOAP-   ENV="http://schemas.xmlsoap.org/soap/
envelope/"  SOAP-
ENV:encodingStyle="http://schemas.xnlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<m:GetLastTradePrice xmlns:m="Some-URI">
<symbol>ORCL</symbol>
<m:GetLastTradePrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

次にレスポンスHTTPメッセージを示します。

HTTP/1.1 200 OK
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn

<SOAP-ENV:Envelope  xmlns:SOAP-
ENV=http://schemas.xmlsoap.org/soap//envelope/ SOAP-
ENV:encodingStyle="http://schemas.xnlsoap.org/soap/encoding/"/>
<SOAP-ENV:Body>
<m:GetLastTradePriceResponse xmlns:m="Some-URI">
<Price>34.5</Price>
</m:GetLastTradePriceResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Oracle SOAPおよびIDAP

IDAPは、AQ操作を実行するためのXMLベースの仕様です。SOAPは、サービスを起動する一般的なメカニズムを定義します。IDAPは、AQ操作を実行する一般的なメカニズムを定義します。

IDAPには、SOAPで定義されない次の重要な特性があります。

  • トランザクションの動作 - トランザクション形式でAQ操作を実行できます。複数のIDAPリクエストに対してトランザクションを実行できます。

  • セキュリティ - すべてのIDAP操作は、認可および認証されたユーザーのみが実行できます。

  • SOAPインタフェースを介してAQ操作を実行することもできます。AQはIDAP形式で操作をカプセル化します。

  • キャラクタ・セット変換 - 変換は、すべての通信において非常に重要な要件です。インターネット・ユーザーのマシンは、サーバー・マシンとはキャラクタ・セットIDが異なる場合があります。

  • AQインターネット操作用の拡張可能なAQサーブレット - AQ操作を実行するAQサーブレットは拡張可能です。AQサーブレットでは、タイムアウト、接続プーリングおよびTAFの指定、XMLスタイルシートの適用、AQ後およびAQ前のデータベース操作の実行が可能です。

エンベロープの名前空間を指定する行を除いて、AQに対するSOAPアクセスとIDAPアクセスに違いはありません。

IDAPの場合、名前空間を指定する行は次のようになります。

<Envelope xmlns="http://ns.oracle.com/AQ/schemas/envelope">

SOAPの場合、名前空間を指定する行は次のようになります。

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">

これ以外はすべて同じです。

SOAPクライアントの概要

SOAPクライアント・アプリケーションは、SOAPリクエストを行うユーザー作成アプリケーションです。SOAPクライアントには次の機能があります。

  • サービスの起動にすべての必要なパラメータを収集します。

  • SOAPサービス・リクエスト・メッセージを作成します。これは、SOAPプロトコルに従って作成されるXMLメッセージであり、XMLでエンコードされたすべての入力パラメータのすべての値を含みます。このプロセスをシリアライズといいます。

  • SOAPサーバーがサポートする転送プロトコルを使用してリクエストをSOAPサーバーに送信します。

  • SOAPレスポンス・メッセージを受信します。

  • SOAP Fault要素を処理して、リクエストの成否を判断します。

  • XMLから戻されたパラメータをネイティブなデータ型に変換します。このプロセスをデシリアライズといいます。

  • 必要に応じて結果を使用します。

SOAPクライアントAPI

SOAPクライアントは、SOAPサービスへのリクエストを構成するXML文書を生成し、SOAPレスポンスを処理します。Oracle SOAPは、有効なSOAPリクエストを送信するすべてのクライアントからのリクエストを処理します。クライアントの開発を容易にするために、Oracle SOAPにはSOAPサービスの起動の汎用的な方法を提供するSOAPクライアントAPIがあります。

SOAPクライアントAPIは、リクエストおよびレスポンス用の同期式起動モデルをサポートし、SOAPリクエストを行うJavaクライアント・アプリケーションの作成を簡略化して、SOAPリクエストの作成および基礎となる転送プロトコルを使用したリクエスト送信の詳細をカプセル化します。また、交換可能な転送をサポートして、クライアントは転送を簡単に変更できます(HTTPおよびHTTPSによる転送が可能)。

SOAPサーバーの概要

SOAPサーバーには次の機能があります。

  • サービス・リクエストを受信します。

  • XMLリクエストの解析後、メッセージを実行するか、拒否するかを決定します。

  • メッセージを実行する場合、リクエストされたサービスが存在するかどうかを判断します。

  • すべての入力パラメータをXMLからサービスが認識できるデータ型に変換します。

  • サービスを起動します。

  • 戻りパラメータをXMLに変換し、SOAPレスポンス・メッセージを生成します。

  • レスポンス・メッセージをコール元に戻します。

Oracle SOAPのセキュリティ機能

Oracle SOAPは、転送時にセキュリティ機能を使用して安全なアクセスをサポートし、その他のセキュリティ機能もサポートします。たとえば、HTTPSを使用して、Secure Sockets Layer(SSL)での機密保護、認証および整合性を提供します。ロギング、認可などのその他のセキュリティ機能は、サービス・プロバイダから提供されます。

SOAPトランスポート

SOAPトランスポートはSOAPメッセージを送信するプロトコルです。Oracle SOAPは、次のトランスポートをサポートします。

  • HTTP: このプロトコルは、基本的なSOAPトランスポートです。Oracle SOAPリクエスト・ハンドラ・サーブレットは、HTTPリクエストを管理し、HTTP上でレスポンスを直接行います。このプロトコルは普及しているため標準になりつつあります。

  • HTTPS: Oracle SOAPリクエスト・ハンドラ・サーブレットは、HTTPSリクエストを管理し、サポートされている様々なセキュリティ・レベルでレスポンスを行います。

管理クライアント

SOAP管理クライアントには、サービス・マネージャとプロバイダ・マネージャがあります。これらの管理クライアントは、新しいサービスやプロバイダの動的なデプロイをサポートするサービスです。

SOAPリクエスト・ハンドラ

SOAPリクエスト・ハンドラは、SOAPリクエストの受信や適切なサービス・プロバイダの検索を行い、リクエストされたメソッド(サービス)を起動するサービス・プロバイダを処理して、SOAPレスポンスを戻す(レスポンスが存在する場合)Javaサーブレットです。

SOAPプロバイダ・インタフェースとプロバイダ

Oracle SOAPには、Javaクラスのプロバイダ実装が含まれます。その他のプロバイダも追加できます。

プロバイダ・インタフェース

プロバイダ・インタフェースを使用すると、SOAPサーバーでプロバイダのタイプ(Javaクラス、ストアド・プロシージャまたはその他のプロバイダ・タイプ)に関係なくサービス・メソッドを一定の方法で起動できます。サービス・プロバイダのタイプごとに、1つのプロバイダ・インタフェース実装があり、すべてのプロバイダ固有情報がカプセル化されます。プロバイダ・インタフェースでは、新しいタイプのサービス・プロバイダをサポートできるように、SOAP実装を簡単に拡張できます。

プロバイダ・デプロイメント管理

Oracle SOAPには、プロバイダのデプロイメント情報を管理するプロバイダ・デプロイメント管理クライアントが用意されています。

提供されるSOAPサービス

SOAPサービスは、SOAPアプリケーションの開発者によって提供されます。これらのサービスは、供給されるデフォルトのJavaクラス・プロバイダまたはカスタム・プロバイダを使用して利用できます。Oracle SOAPには、SOAPサービスを管理するサービスとして実行する、サービス・デプロイメント管理クライアントが含まれます。SOAPサービス(Javaサービスを含む)とは、リモートSOAPクライアントに提供されるユーザー作成アプリケーションを意味します。

EDIでのXMLの利点

次に、電子データ交換(EDI)の現状について説明します。

  • 難解なテクノロジ: EDIでは、開発者による読取りや理解が簡単にできない形式でマシン間の通信が可能です。

  • EDIメッセージのデバッグは非常に困難です。XML文書は読取り可能で編集が容易です。

  • 柔軟性の低さ: 既存のシステムの一部として新規の取引先を追加することは非常に困難です。新規の取引先ごとに個別のマッピングが必要です。XMLは柔軟性がきわめて高く、必要に応じて新しいタグを追加したり、XML文書を他のXML文書に変換したりする(2つの異なる形式の発注書番号をマップするなど)機能があります。

  • 高コスト: 開発者の養成コストが高く、EDIのデプロイには、特殊ネットワークを要するきわめて高性能のサーバーが必要です。EDIは高コストな付加価値通信網(Value Added Network)で実行されます。XMLは既存のインターネット接続を介して低コストなWebサーバーで機能します。


    関連資料:

    Oracle SOAPとWebサービスの詳細(ドキュメントやダウンロードなど)は、次の関連資料を参照してください。
    • OracleAS SOAPの開発者用ガイドは、http://www.oracle.com/technology/documentation/ias.htmlにあります。

    • 『Oracle Simple Object Access Protocol Developer's Guide』

    • AQへのインターネット・アクセスの詳細は、『Oracle Streamsアドバンスト・キューイング・ユーザーズ・ガイドおよびリファレンス』を参照してください。

    • 『Oracle XML APIリファレンス』

    • SOAP APIは、doc/readmes/ADDEN_rdbms.htmファイルのプロダクトCD(ディスク1)にあります。


SOAPのサンプル

本社や複数のリモート支社で管理する在庫を持つ企業エンティティまたは行政エンティティについて考えてみます。この章で説明するSOAPソリューションは、本社をメッセージ・サーバーとして、支社をメッセージ・クライアントとして考えます。次の複数のタスクが実行されます。

HQの在庫監視と、新しいアイテムがHQの在庫に追加された場合の支社への通知タスクについて考えます。この例では、SOAPメッセージ機能と複数のXML機能を使用してこの問題を解決します。

SOAPはどのDBMSにも依存しないため、支社ではOracle以外のデータベースを使用できます。この例を一般化して、組織の一部ではない顧客、サプライヤまたはその他のエンティティとの通信に使用できます。

SOAPのサンプルで使用するXMLの機能

SOAPメッセージでは次の機能を使用します。

  • アドバンスト・キューイング(AQ)。このOracle機能は、アプリケーションとユーザー間の非同期通信を使用して、トランザクションの制御およびセキュリティが提供されます。AQを使用すると、ユーザーが新しい在庫アイテムをHQで入力する場合にブロックされません。

  • AQはメッセージをエンキューおよびデキューするJava Messaging Service(JMS)APIを提供します。

  • XMLTypeデータ型の列を使用して、SOAPメッセージをデータベース表に格納するため、新しいアイテムに関するデータが失われません。

  • XML圧縮によって、ペイロードのサイズが縮小され、メッセージの転送速度が向上します。

  • XSQLサーブレットを使用して、コンテンツの公開や管理者との対話を行います。

  • HQのメッセージ・サーバーがリモート・プロシージャ・コール(RPC)を起動します。

  • SOAPコールはHTTPリクエストを生成し、SOAPメッセージの在庫更新リクエストをカプセル化して、すべての支社でSOAPサービスを起動します。

  • 各支社は、メッセージ・サーバーに確認を戻すか、またはFalut(SOAP標準で定義)を戻します。

SOAPサンプルに必要なソフトウェア

  • Oracle Database

  • XML Developer's Kit(XDK)、Javaコンポーネント

  • OC4J

  • SOAPサンプル「Build an XML-Powered Distributed Application」(OTNからダウンロード可能)


    関連資料:

    http://www.oracle.com/technology/tech/xml/にあるSOAPサンプルをダウンロードします。

SOAPサンプルの実装方法

次の図に、分散在庫アプリケーションの概要を示します。

図11-1 分散在庫アプリケーションでのSOAPの使用

図11-1の説明が続きます
「図11-1 分散在庫アプリケーションでのSOAPの使用」の説明

SOAPを使用して、各リモート支社と本社で在庫を管理します。本社の在庫アプリケーションはメッセージ・サーバーであり、支社の在庫アプリケーションはメッセージ・クライアントです。どちらもSOAPサービスを使用します。

本社で在庫に新しいアイテムを追加すると、メッセージ・サーバーに登録したすべてのリモート・クライアント支社にメッセージが配信されます。メッセージ・ブローカはメッセージを作成し、AQを使用してこのメッセージをメッセージ・キューに入れます。AQを使用すると、ユーザー・アプリケーション間での非同期通信が可能になり、トランザクションの制御とセキュリティが提供され、本社のユーザーによる新しいアイテムのエントリがブロックされません。

メッセージ・キューにリスニングするメッセージ・ディスパッチャ・プロセスは、エンキューしたメッセージを検出して、支社のSOAPサービスをコールし、メッセージのデキューやローカルの在庫更新を行います。

メッセージはログ情報の詳細とともにデータベースに格納されます。SOAPメッセージはXMLTypeデータ型インスタンスに格納され、送受信メッセージのレコードになります。これにより、在庫内のデータの整合性が保証されます。

本社では3つの列(識別番号、XMLTypeデータ型のメッセージおよび作成時間)からなる表が最初に作成されます。

もう1つのテクノロジはペイロードの軽減に使用するXML圧縮です。XML圧縮により、大規模なアプリケーションでのスループットが向上します。

表とSOAPサービスの設定

在庫データとログ・メッセージを格納して、メッセージ・キューイングを実行するには、ダウンロードしたソース・ファイルからcreatedb.sqlスクリプトを実行して、本社および支社にデータベース・スキーマを設定します。このスクリプトは、適切な権限を持つ本社のユーザーと支社のユーザーを作成するSQLスクリプトのセットをコールします。また、在庫情報やメッセージを格納するための表やトリガーを作成して、両方のスキーマにサンプル・データを挿入します。

本社のユーザー・スキーマでは、message_out_typeという名前の表を作成します。この表が、本社から支社への在庫情報更新のブロードキャスト・メッセージを格納します。表にはIDMESSAGEおよびCREATE_TIMEという3つの列があります。MESSAGE列のデータ型はXMLTypeです。

次に、本社および支社の両方でメッセージ・キューを設定するPL/SQLプロシージャCREATE_QUEUEを実行します。このプロシージャはDBMS_AQADMパッケージのファンクションを使用して、キュー表とキューを作成し、キューを開始します。キューを開始したら、メッセージ・キューに対するエンキュー操作およびデキュー操作が可能になります。

次のPL/SQLプロシージャはSYS.AQ$_JMS_BYTES_MESSAGEメッセージ・タイプを使用して、圧縮したSOAPメッセージを管理します。このプロシージャにより、本社でbroadcastb_queueというキューが作成されます。

begin
    create_queue('broadcastb_queue_tbl',
    'broadcastb_queue',
    'SYS.AQ$_JMS_BYTES_MESSAGE');
end;

inventoryBranchServer Javaクラスは、新しいアイテムを支社の在庫に挿入するための支社のサービスです。このサービス・プログラムがSOAPリクエストを受信すると、リクエストのコンテンツが解凍され、データベースにアイテムを挿入するOracle XML SQL Utility(XSU)によってinventory_item表に保存されます。Oracle XSUでは、XML文書とデータベース・スキーマ間の正規マッピングを作成し、SQLデータ操作を実行します。次のファイルを参照してください。

client/src/oracle/xml/pm/demo/branch/service/inventoryServer.java

これはダウンロードしたソフトウェアにあります。

SOAPサービスのリクエスト

アプリケーションは、insertItemServletと呼ばれるサーブレット(HttpServletを拡張するJavaクラス)を使用し、本社に対してSOAPサービスのリクエストを行います。このサーブレットは本社の在庫に新しいアイテムを挿入します。

サーブレット・リクエストはXSQLページとアプリケーションのWebインタフェース(「新規アイテム」をクリック)のユーザー入力を使用してXML文書を生成します。Oracle XSUはXMLのコンテンツをデータベースに直接挿入します。insertItemServletは複数のアクションを実行します。たとえば、更新メッセージを支社に配信するために、次のアクションを実行します。

  • メッセージ・ディスパッチャ・プロセスを初期化します。

  • CompressionAgentクラスをコールして、XML文書を圧縮します。

  • SOAPメッセージを作成して、メッセージ・ロギング表に格納します。

  • 圧縮したXML文書をメッセージ・キューに入れます(エンキュー)。

MessageDispatcherプロセスの初期化

insertItemServletを最初にコールすると、MessageDispatcherオブジェクトが初期化されます。このオブジェクトは、プロセスの初期化が成功するとServletContextに格納されます。次のコードはMessageDispatcherオブジェクトを初期化します。

ServletContext context = getServletContext();
MessageDispatcher msgDispatcher =
    (MessageDispatcher)context.getAttribute("Dispatcher");

if (msgDispatcher == null) {
   System.out.println("Initialize Receiver.");
   msgDispatcher = new MesageDispatcher();
   context.setAttribute("Dispatcher",msgDispatcher);
   }

MessageDispatcher Javaクラスは、MessageClientを順番に作成して、各メッセージ・キューの監視と登録した支社へのメッセージのディスパッチを行うMessageBrokerを作成します。

XML文書の圧縮

insertItemServletからの次のコードでは、圧縮エージェントを作成します。

CompressionAgent cagent = new
   CompressionAgent("oracle:compression");
byte [] input = cagent.compression(m_content);

SOAPメッセージの作成

メッセージはXMLTypeとして定義された列に格納されます。SOAPメッセージを作成し、MESSAGE_OUT_XMLTYPE表に格納するinsertItemServletからのコードは次のようになります。

OraclePreparedStatement pstmt =
    (OraclePreparedStatement) conn.prepareStatement (
          "Insert into message_out_xmltype(message) values(?)");

m_content=createSOAPMessage(m_content);
oracle.xdb.XMLType xt = oracle.xdb.XMLType.createXML(conn,m_content);

pstmt.setObject(1, xt);
pstmt.execute();

XMLTypeを使用すると、sys.XMLType.extract()メンバー関数でXPATHを使用し、メッセージ・ドキュメントの一部に問合せを行うことができます。

select e.message.extract('//item_info')
   .getStringVal() as result
from message_out_xmltype;

XML文書のエンキュー

insertItemServletからの次のコードは、MessageBrokerを作成して、メッセージをエンキューします。

MessageBroker mesgBroker =
   new MessageBroker("host_name",
   "Oracle_SID", "port_num",
   "thin", "cm", "cm", "broadcastb_queue");
mesgBroker.enqueueMessage(input);

insertItemServletが完了すると、メッセージはメッセージ・キューに入れられ、Oracle AQおよびMessageDispatcherプロセスが支社の在庫情報を更新します。これで、本社の在庫システムが支社のシステム更新中にブロックされることはありません。

Javaソース・ファイルinserItemServlet.javaのリスト

このファイルは./server/src/insertItemServlet.javaにあります。

/**
 * FileName: insertItemServlet.java
 * Description:
 *   Insert new Inventory Item into HQ database and broadcase the message to
 *   the branches.
 */
import java.io.*;
import java.util.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;

// XSU
import org.w3c.dom.*;
import oracle.xml.parser.v2.*;
import oracle.xml.sql.dml.OracleXMLSave;

// XMLType
import oracle.xdb.XMLType.*;
import oracle.jdbc.driver.*;
import oracle.sql.*;

// SOAP Message
import oracle.AQ.*;
import oracle.xml.pm.queue.*;
import oracle.xml.pm.compression.CompressionAgent;

// Configuration
import oracle.xml.pm.util.ConfigManager;

/**
 * This class implements Message Borker
 */
public class insertItemServlet extends HttpServlet
{
  String m_content=null;
  String m_dblink = null;
  String m_usr = null;
  String m_passwd = null;
  String m_hostname = null;
  String m_sid = null;
  String m_port = null;

  /**
   * Initialize global variables
   * @param config - ServletConfig
   * @exeception - ServletException thrown if super.init fails
   */
  public void init(ServletConfig config) throws ServletException
  {
    super.init(config);

    // Initialize the JDBC Connection from Configuration Files
    try
    {
      ConfigManager xml_config = new ConfigManager("DEMOConfig.xml","cm");
      m_dblink = xml_config.dblink;
      m_usr= xml_config.usr;
      m_passwd = xml_config.passwd;
      m_hostname = xml_config.hostname;
      m_sid = xml_config.db_sid;
      m_port = xml_config.db_port;
    }
    catch(Exception ex)
    {
      // ex.printStackTrace();
      throw new ServletException(ex.getMessage());
    }
  }

  /**
   * HTTP Get
   * @param req - HttpServletRequest
   * @param res - HttpServletResponse
   * @exeception - IOException, ServletException
   */
   public void doGet(HttpServletRequest req, HttpServletResponse res)
       throws IOException, ServletException
  {
     doPost(req,res);
  }

  /**
   * HTTP POST
   * @param req - HttpServletRequest
   * @param res - HttpServletResponse
   * @exeception - IOException, ServletException
   */
  public void doPost(HttpServletRequest req, HttpServletResponse res)
  throws IOException, ServletException
  {
    ServletContext context = getServletContext();

    // Initialize MessageDispatcher for broadcast messages
    MessageDispatcher msgDispatcher =
      (MessageDispatcher) context.getAttribute("MessageDispatcher");

    if(msgDispatcher == null)
    {
        msgDispatcher = new MessageDispatcher("broadcastb_queue",m_hostname,
        m_sid, m_port, m_usr,m_passwd,m_dblink);
        context.setAttribute("MessageDispatcher",msgDispatcher);
     }

    // Initialize MessageBroker for broadcasting messages
    MessageBroker msgBroker = (MessageBroker)
                                  context.getAttribute("MessageBroker");
    if(msgBroker == null)
    {
      try
      {
        msgBroker = new MessageBroker(m_hostname, m_sid, m_port, "thin",m_usr,
                                      m_passwd,"broadcastb_queue",m_dblink);
        context.setAttribute("MessageBroker",msgBroker);
      }
      catch(Exception ex)
      {
        System.out.println("Error:"+ex.getMessage());
      }
    }

    PrintWriter out = res.getWriter();
    m_content = req.getParameter("content");

    // Save new Item information into database
    try
    {
      Connection conn = getConnection();

      OracleXMLSave sav = new OracleXMLSave(conn,"inventory_item_view");
      sav.insertXML(m_content);
      sav.close();
      conn.close();

      out.println("Insert Successful\n");
    }
    catch(Exception e)
    {
      out.println("Exception caught "+e.getMessage());
      return;
    }

    // Create and Enqueue the Message
    byte[] input = createMessage(m_content);
    msgBroker.enqueueBytesMessage(input);

    return;
  }

  // Subject to change to validate and using XML Update language
  // Since this message is not public we keep it with simplified SOAP format
  public byte[] createMessage(String content)
  {
     String message = null;

     message="<Envelope>"+
            "<Header>"+
            "<branch_sql>"+"select id,soapurl from branch"+"</branch_sql>"+
            "<objURI>"+"inventoryServer"+"</objURI>"+
            "<method>"+"addItem"+"</method>"+
            "</Header>"+
            "<Body>"+content+"</Body>"+
            "</Envelope>";

    // Compress the Message Content
    CompressionAgent cagent = new CompressionAgent("oracle:xml:compression");
    byte [] input = cagent.compress(message);

    return input;
  }

  /**
   * Get JDBC Connection
   * @return Connection - JDBC Connection
   * @exception SQLException - thrown if the connection can't be gotten.
   */
  public Connection getConnection() throws SQLException
  {
    DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
    Connection conn =DriverManager.getConnection (m_dblink,m_usr,m_passwd);
    return conn;
  }
}

AQを使用したメッセージのキューイング

MessageBrokerクラスはメッセージ・キューと通信するエージェントであり、SOAPリモート・プロシージャ・コール(RPC)を起動します。

MessageBrokerには次の機能があります。

メッセージのエンキューとデキュー

AQはメッセージをエンキューおよびデキューする標準のJava Messaging Service(JMS)APIを提供します。ただし、これらの操作の前に、QueueConnectionを取得して、これによってQueueSessionを作成し、メッセージ・キューを取得する必要があります。それぞれのQueueSessionでは、トランザクションの制御にQueueSessioncommit()が使用されます。メッセージ・システムでメッセージを支社に送信する際になんらかの不具合が発生した場合、コミットは行われず、メッセージはデータベースに残ります。

リモートSOAPサービスの起動

MessageBrokerは、(RPCCall Javaクラスにある)RPCCallエージェントでリモートSOAPサービスを起動します。SOAP RPCCallはCallオブジェクトを作成してSOAPサービスを指定し、パラメータをCallオブジェクトのパラメータのベクターに追加します。CallオブジェクトはリモートSOAPサービスを起動して、エラーがある場合はFaultコードを戻します。サービス情報を記述するには、サービスJavaクラス内にサービス・オブジェクトを定義します。

SOAPコールはHTTPリクエストを生成し、SOAPメッセージの在庫更新リクエストをカプセル化して、すべての支社でSOAPサービスを起動します。本社が支社の在庫サービスをコールすると、支社は本社に確認を送信します。

XMLの圧縮

メッセージ・システムの効率を上げるには、XMLの圧縮を使用します。XMLの圧縮では、次のようなJavaオブジェクトのシリアライズを使用して、メッセージを圧縮または解凍します。

XMLDocument.writeExternal(...);
XMLDocument.readExternal(...);

サンプル・アプリケーションではCompressionAgent Javaクラスを使用して、圧縮機能と解凍機能を提供しています。CompressionAgentには、圧縮メソッドと解凍メソッドが含まれています。圧縮メソッドはバイト配列を戻し、解凍メソッドはXML文書を戻します。

Javaソース・ファイルMessageBroker.javaのリスト

この長いソース・ファイルは./xmlagents/src/oracle/xml/pm/queueにあります。

比較的重要なファンクションとして、SOAPファイルを送信するsendSOAPMessage()と、各在庫アイテムの情報をデキューするdequeueTextMessage()があります。

SOAPサンプルの概要

SOAPメッセージ・システムでAQおよびXDKを使用すると、信頼性とパフォーマンスが大幅に向上する可能性があります。在庫更新メッセージはすぐに配信されます。メッセージを配信できない場合、再送信するために格納され、ログとして記録されます。これらの機能により、信頼性のある非同期メッセージ・キューイングが実現し、XMLメッセージ・データの転送速度が上がります。