ヘッダーをスキップ
Oracle® Fusion Middleware Oracle WebLogic Server JAX-WS を使用した Web サービスの高度な機能のプログラミング
11g リリース 1 (10.3.1)
B55543-01
  目次
目次

戻る
戻る
 
次へ
次へ
 

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

以下の節では、SOAP メッセージ ハンドラの作成と使用について説明します。

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

Web サービスおよびそのクライアントは、メッセージのリクエストや応答の追加処理において、SOAP メッセージにアクセスしなければならないときがあります。SOAP メッセージ ハンドラを作成すると、WebLogic Server およびクライアントがこの 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 Fusion Middleware JAX-WS を使用した Oracle WebLogic Server Web サービス入門』を参照してください。

表 8-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 Fusion Middleware JAX-WS を使用した Oracle WebLogic Server Web サービス入門』の「スタンドアロン クライアントからの Web サービスの呼び出し : 主な手順」を参照してください。

表 8-2 クライアントサイド 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 メソッドが実行される順序を示しています。

図 8-1 ハンドラ メソッドの実行順序

周囲のテキストは図 8-1を説明します。

クライアントサイド ハンドラの実行

クライアントサイド ハンドラの場合は、以下のタイミングで二度実行されます。

  • クライアント アプリケーションが Web サービスに SOAP リクエストを送信する直前

  • クライアント アプリケーションが Web サービスから SOAP 応答を受信した直後

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

SOAP メッセージ ハンドラには 2 つのタイプがあります。次の表にそれぞれの定義を示します。

表 8-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://java.sun.com/javase/6/docs/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://java.sun.com/javase/6/docs/api/javax/xml/ws/LogicalMessage.html を参照)。


両方のタイプのメッセージ ハンドラが拡張する javax.xml.ws.Handler インタフェースは、次の表に示すメソッドを定義します。(http://java.sun.com/javase/6/docs/api/javax/xml/ws/handler/Handler.html を参照)。

表 8-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://java.sun.com/javase/6/docs/api/javax/xml/ws/handler/MessageContext.html を参照)。ハンドラ チェーン内のハンドラは、MessageContext プロパティを使用して、メッセージが着信か発信かを識別し、処理状態を共有します。MessageContextSOAPMessageContext または LogicalMessageContext サブインタフェースを使用すると、SOAP メッセージまたは論理メッセージの内容を取得したり設定したりできます。詳細については、「メッセージ コンテキスト プロパティの値とメソッドの使用」を参照してください。

SOAP メッセージのすべての処理をコーディングしたら、以下のシナリオのいずれかをコーディングします。

  • true を返すことにより、ハンドラ リクエスト チェーン内の次のハンドラを呼び出す。

    リクエスト チェーンの次のハンドラは、@HandlerChain アノテーションによって指定されたコンフィグレーション ファイル内の <handler-chain> 要素の次の <handler> 下位要素として指定されます。

  • false を返すことにより、ハンドラ リクエスト チェーンの処理をブロックする。

    ハンドラ リクエスト チェーンの処理をブロックすると、Web サービスのこの呼び出しについては、バックエンド コンポーネントは実行されなくなります。Web サービスの一部の呼び出しの結果をキャッシュしてあり、そのリストに現在の呼び出しも含まれている場合は、この操作が便利な場合があります。

    ハンドラ リクエスト チェーンの処理は中断されますが、WebLogic Server が、現在のハンドラから順に、response チェーンを呼び出します。

  • ハンドラに固有のすべての実行時エラーに対して、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://java.sun.com/javase/6/docs/api/javax/xml/ws/handler/MessageContext.html を参照)。ハンドラ チェーン内のハンドラは、MessageContext プロパティを使用して、メッセージが着信か発信かを識別し、処理状態を共有します。MessageContextLogicalMessageContext または SOAPMessageContext サブインタフェースを使用すると、SOAP メッセージまたは論理メッセージの内容を取得したり設定したりできます。詳細については、「メッセージ コンテキスト プロパティの値とメソッドの使用」を参照してください。

SOAP 障害のすべての処理をコーディングしたら、次のいずれかを実行します。

  • true を返すことにより、ハンドラ チェーン内の次のハンドラの handleFault() メソッドを呼び出す。

  • false を返すことにより、ハンドラ障害チェーンの処理をブロックする。

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

Handler.close() は、メッセージ交換を完了し、処理の間にアクセスしたリソースをクリーンアップします。そのシグネチャは次のとおりです。

public boolean close(MessageContext context) {}

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

SOAP メッセージ ハンドラには、以下のコンテキスト オブジェクトが渡されます。

表 8-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 Fusion Middleware JAX-WS を使用した Oracle WebLogic Server Web サービス入門』の「MessageContext プロパティ値の使用」を参照してください。

LogicalMessageContext クラスは、論理メッセージを処理する次のメソッドを定義します。詳細については、(http://java.sun.com/javase/6/docs/api/javax/xml/ws/handler/LogicalMessageContext.html) の java.xml.ws.handler.LogicalMessageContext Javadoc を参照してください。

表 8-6 LogicalMessageContext クラスのメソッド

メソッド 説明
getMessage()

SOAPメッセージを含む javax.xml.ws.LogicalMessage オブジェクトを取得します。


SOAPMessageContext クラスは、SOAP メッセージを処理する以下のメソッドを定義します。詳細については、(http://java.sun.com/javase/6/docs/api/javax/xml/ws/handler/soap/SOAPMessageContext.html) の java.xml.ws.handler.soap.SOAPMessageContext Javadoc を参照してください。


注意 :

SOAP メッセージ自体は、(http://java.sun.com/javase/6/docs/api/javax/xml/soap/SOAPMessage.html) の javax.xml.soap.SOAPMessage オブジェクトに格納されています。このオブジェクトの詳細については、「SAAJ を使用した SOAP リクエスト メッセージおよび応答メッセージの直接操作」を参照してください。

表 8-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 オブジェクトには、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://java.sun.com/javase/6/docs/api/javax/xml/soap/AttachmentPart.html を参照。) SOAP メッセージに対するオプションの添付ファイルが入っています。添付ファイルは、SOAP メッセージの残りの部分とは異なり、XML フォーマットの必須部分ではないので、その形式は、単純なテキストからイメージ ファイルまで、さまざまです。


注意 :

SOAP メッセージ ハンドラから直接に添付ファイル java.awt.Image にアクセスする場合は、「SOAP メッセージ ハンドラで画像添付ファイルの操作」で重要情報を参照してください。

添付ファイルを操作するには、SOAPMessage クラスの以下のメソッドを使用します。詳細については、(http://java.sun.com/javase/6/docs/api/javax/xml/soap/SOAPMessage.html) の javax.xml.soap.SOAPMessage Javadoc を参照してください。

表 8-8 添付ファイルの操作に使用する SOAPMessage クラスのメソッド

メソッド 説明
addAttachmentPart()

作成された AttachmentPart オブジェクトを SOAPMessage に追加します。

countAttachments()

この SOAP メッセージに含まれている添付ファイルの数を返します。

createAttachmentPart()

他のタイプの Object から AttachmentPart オブジェクトを作成します。

getAttachments()

すべての添付ファイルを AttachmentPart オブジェクトとして取得し、Iterator オブジェクトに格納します。


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

この節では、添付ファイル java.awt.Image にアクセスする SOAP メッセージ ハンドラを作成すること、および clientgen Ant タスクによって生成されたクライアント JAX-RPC スタブを使用するクライアント アプリケーションから Image が送信されていることを前提としています。

clientgen Ant タスクによって生成されたクライアント コードでは、添付ファイル java.awt.Imageimage/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 アノテーションの詳細については、http://www.jcp.org/en/jsr/detail?id=181 にある Web Services Metadata for the Java Platform 仕様を参照してください。

ハンドラ チェーン コンフィグレーション ファイルの作成

前の節で説明したように、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 スキーマ、その作成に関する詳細、およびさらなるサンプルについては、http://www.jcp.org/en/jsr/detail?id=181 にある Web Services Metadata for the Java Platform 仕様を参照してください。

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

この節では、Web サービスをコンパイルおよびビルドする作業用の build.xml Ant ファイルがあり、ハンドラ チェーンが含まれるように、そのビルド ファイルを更新することを想定しています。この build.xml ファイルの作成については、『Oracle Fusion Middleware JAX-WS を使用した Oracle WebLogic Server Web サービス入門』の「WebLogic Web サービスの開発」を参照してください。

メッセージ ハンドラのコンパイルとビルドが含まれるように開発環境を更新するには、以下のガイドラインに従います。

クライアントサイド SOAP メッセージ ハンドラのコンフィグレーション

クライアントサイド SOAP メッセージ ハンドラは、以下のいずれかの方法で定義できます。