特集
次世代XML Webサービスを試す Part 4

4.ほかのWS-Attachments実装との相互運用

インフォテリア株式会社
吉松 史彰
2003/04/02

Page1 Page2 Page3 Page4

ほかのWS-Attachments実装との相互運用

 DIMEはMicrosoftの独自仕様であるにもかかわらず、さまざまな製品にすでに実装されている。そこで今回は、DIMEを実装しているApache Axis(JavaベースのSOAPの実装)を使って、DIMEメッセージの相互運用を試してみる(Apache Axisとの相互運用は、本連載Part1でもWS-Security実装を用いて行っているので参考にしていただきたい)。

■WSEクライアントからAxisサーバへ添付ファイル付きDIMEメッセージを送信

 まずAxisベースのWebサービスを次の手順で開発する。

サービスの実体を作成する

 次のコードが添付ファイルを受け取るWebサービスになる。詳細は割愛するが、受け取った添付ファイルの内容をそのまま所定のフォルダに保存しているだけだ。このソース・コードをコンパイルして.classファイルを作成する。

import java.io.InputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.soap.SOAPException;

import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.attachments.Attachments;
import org.apache.axis.attachments.AttachmentPart;

public class AxisDIME {
  public String PutData(String originalName) throws SOAPException {
    try {
      MessageContext ctx = MessageContext.getCurrentContext();
      Message msg = ctx.getRequestMessage();
      AttachmentPart part
          = (AttachmentPart)msg.getAttachments().next();

      FileOutputStream fs = new FileOutputStream(
                "C:\\Inetpub\\wwwroot\\WSEDIME\\incoming\\"
                + originalName);
      part.getDataHandler().writeTo(fs);
      fs.close();

      return "http://localhost/WSEDIME/incoming/" + originalName;
    } catch (IOException ioex) {
      ioex.printStackTrace();
      throw new SOAPException("error", ioex);
    }
  }
}
添付ファイルを受け取るAxisベースのWebサービス
受け取った添付ファイルの内容をそのまま所定のフォルダに保存する。

Apache Axisにクラスを配置する

 Axisはサーブレットなので、実行時にロードするクラスはWEB-INF/classesフォルダにコピーしておけばよい。ここでは上記のソース・コードをコンパイルしてできたAxisDIME.classをコピーした。

Apache Axisでサービスを公開する

 下記のようなXMLファイルを作成し、deploy.wsddという名前で保存する。

<deployment xmlns="http://xml.apache.org/axis/wsdd/"
            xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="AxisDIME" provider="java:RPC">
  <parameter name="className" value="AxisDIME"/>
  <parameter name="allowedMethods" value="*"/>
</service>
</deployment>
Apache AxisでWebサービスを公開するための設定ファイル

 上記のファイルを使って次のコマンドで設定する。

% java org.apache.axis.client.AdminClient deploy.wsdd

 これでサービスができたので、WSEのクライアントを少し改造して、Apache Axisのサービスにアクセスするようにしよう。

WSEDIMEClientプロジェクトを開いて、フォームにボタンを1つ追加する。

Web参照を追加する。

 Apache Axisが起動していれば、

http://localhost:8080/axis/services/AxisDIME?wsdl

というURLでWSDLが取得できる。なお、Web参照で作成されたソース・コード内のURLには、なぜかポート番号が設定されないことがあるので、[Web References]からReference.csファイルを開いてUrlプロパティを設定しているコードにポート番号を手動で付け加える必要がある。

ボタンのClickイベントのイベント・ハンドラを実装する。

 次のコードでAxisのWebサービスにアクセスできる。内容はWSEのサービスにアクセスするときとほとんど同じで、WS-Routingのヘッダ生成をオプションにしているコードだけが異なっている。

private void button2_Click(object sender, System.EventArgs e) {
  localhost1.AxisDIMEServiceWse svc
      = new localhost1.AxisDIMEServiceWse();
  svc.RequestSoapContext.Path.MustUnderstand = false;
  openFileDialog1.CheckFileExists = true;
  if (openFileDialog1.ShowDialog() == DialogResult.OK) {
    System.IO.Stream str = openFileDialog1.OpenFile();
    svc.RequestSoapContext.Attachments.Add(
        new DimeAttachment("image/jpeg",
        TypeFormatEnum.MediaType, str));
    textBox1.Text = svc.PutData(
        new System.IO.FileInfo(openFileDialog1.FileName).Name);
    str.Close();
  }
}
AxisのWebサービスを呼び出すボタンのイベント・ハンドラ
WSEで実装したWebサービスを呼び出す場合とほぼ同じ内容となっている。変更点は、WS-Routingのヘッダを付加しないように、MustUnderstandプロパティをfalseに設定している行だけだ。

 これでクライアントも完成だ。クライアント・アプリケーションを実行して、ボタン2をクリックし、ファイルを選択すればAxisがそれを受け取って保存してくれる。特に設定や実装で苦労は何もなく、拍子抜けするほどすんなり接続できた。

■AxisクライアントからWSEサーバへ添付ファイル付きDIMEメッセージを送信

 今度は逆に、AxisのクライアントからWSEのサーバへ添付ファイル付きのDIMEメッセージを送信してみる。

Javaのクライアントを作成する

 ここでは次のような実装を行った。コードは少々長いのだが、やっていることはダイアログ・ボックスを開いてファイルを選択させ、選択されたファイルを開いてDIMEメッセージとして送信しているだけである。

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory;
import org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.xml.rpc.ParameterMode;
import javax.xml.namespace.QName;
import java.net.URL;

public class AxisDIMEClient {
  public static void main(String[] args) throws Exception {
    FileDialog dlg = new FileDialog(new Shell(), SWT.OPEN);
    String fileName = dlg.open();
    if (fileName != null) {
      DataHandler dhSource
          = new DataHandler(new FileDataSource(fileName));
      Service service = new Service();
      Call call = (Call)service.createCall();
      call.setTargetEndpointAddress(
          new URL("http://localhost/WSEDIME/Service1.asmx"));
      call.setOperationStyle("wrapped");
      call.setOperationName(
          new QName("http://tempuri.org/", "PutData"));
      call.setReturnQName(
          new QName("http://tempuri.org/", "PutDataResult"));
      call.setReturnType(
          new QName("http://www.w3.org/2001/XMLSchema", "string"),
          String.class);
      call.setUseSOAPAction(true);
      call.setSOAPActionURI("http://tempuri.org/PutData");
      call.setEncodingStyle(null);
      call.setScopedProperty(
          org.apache.axis.client.Call.SEND_TYPE_ATTR,
          Boolean.FALSE);
      call.setScopedProperty(
          org.apache.axis.AxisEngine.PROP_DOMULTIREFS,
          Boolean.FALSE);

      QName att = new QName("http://tempuri.org/", "DataHandler");
      call.registerTypeMapping(dhSource.getClass(),
          att, JAFDataHandlerSerializerFactory.class,
          JAFDataHandlerDeserializerFactory.class);
      call.addParameter(
          new QName("http://tempuri.org/", "originalName"),
          new QName("http://www.w3.org/2001/XMLSchema", "string"),
          String.class, ParameterMode.IN);
      call.addParameter("data", att, ParameterMode.IN);
      call.setProperty(Call.ATTACHMENT_ENCAPSULATION_FORMAT,
          Call.ATTACHMENT_ENCAPSULATION_FORMAT_DIME);

      Object ret = call.invoke(new Object[]
          { new java.io.File(fileName).getName(), dhSource } );
    }
  }
}
WSEのWebサービスにアクセスするJavaのクライアント
コードは少々長いが、処理内容は.NET版と同じで、ダイアログ・ボックスを開いてファイルを選択させ、選択されたファイルを開いてDIMEメッセージとして送信しているだけだ。

上記のソース・コードをコンパイルする。

% javac AxisDIMEClient.java

 ここではEclipse(オープンソースのJava開発環境)に付属しているSWT(Simple Widget Kit:Java用のGUIツールキット)を利用しているので、swt.jarファイルにCLASSPATH環境変数が通っている必要がある。

 これで実装は完了だ。次のコマンドでクライアントを実行し、ダイアログ・ボックスでファイルを選択すれば、WSEのサービスがファイルを受け取って保存してくれる。送信されるDIMEメッセージも、仕様がかっちり決まっているだけに、違いは全くない。

% java AxisDIMEClient

 以上のとおり、Apache AxisとWSEの間で簡単なDIMEメッセージの送受信は全く問題なく行える。

まとめ

 WSEに関する内容はこれで一通り解説できた。もっとも、MicrosoftとIBMが中心になって進めているGXAには、WS-XXXという名前の仕様がまだまだたくさん存在する。WSEが実装しているのはそのうちのごく一部に過ぎず、システム開発者にとって興味深いであろうWS-Transactionのような仕様はまだ実装されていない。これらの仕様の実装がWSEのバージョンアップという形態で出てくるのかどうかもまだ分からないが、Webサービスが成熟するにつれてこれらの実装も世に出てくるはずだ。もし何か試せる環境が入手できたらまたレポートしたい。それではまた会う日まで。End of Article

追記
 2003年2月26日付けで、Microsoftは「XML, SOAP, and Binary Data 」という文書を公開した。この文書の中で提起されている問題を要約すると、次のようなことが記述されている。

 本稿で触れたWS-AttachmentsやSOAP Messages with Attachmentsの仕様は、XMLベースのメッセージング・フレームワークであるSOAPで前提となっているXMLベースのデータ・モデル以外に、MIMEマルチパートやDIMEで表現されるもう1つのデータ・モデルを、XML Webサービスの世界に導入している。ほかのほとんどのWS-XXX仕様は、SOAPメッセージのデータ・モデルに対して、例えば秘匿性(暗号化)、完全性(デジタル署名)、ルーティングなどのインフラを提供するものであるため、DIMEやMIMEマルチパートが持つデータ・モデルとの一貫性が必ずしも考慮されていない。例えば、WS-Attachments仕様に準拠したメッセージに、WS-Security仕様のヘッダを付けてメッセージの「完全性」を保証しようとしても、それがDIMEの2つ目以降のペイロードの完全性まで保証するのかどうかわからないことになる。これでは非常に都合が悪い。

 問題を解決する手立ては、上記のようないくつかの文書でも提案されている。例えば、XIncludeのメカニズムをバイナリ・データにも利用できれば、XMLのデータ・モデルにバイナリ・データを「含んだ」形になるかもしれない。あるいは、XMLをXML 1.0仕様で規定されたテキスト・データではなくバイナリで表現する形式を作ることも考えられる。XMLそのものがバイナリで表現されれば、その中に含まれるバイナリ・データはバイナリのままで送受信できるからだ。

 どうやら現在Microsoftでは、「XML WebサービスがXMLのデータ・モデルを利用する仕組みである以上、やはりバイナリ・データもXMLのデータ・モデルに含められる形で送受信された方がよいのではないか」という考えがあるようだ。SOAP Messages with AttachmentsというMIMEマルチパートを利用した仕様は、Microsoftから提案されたものの、Microsoftはそれを実装せずにあきらめた。現状を考えると、DIMEやWS-Attachmentsの将来についても、すでに固定された仕様と考えるのではなく、まだ流動的なものとして継続的にウォッチしていかなければならないことだけは間違いない。

追記 その2
 
その後、2003年3月24日付けでMicrosoft、BEA、AT&T、SAP、TIBCO、CANONの各社に属する技術者が連名で、「Proposed Infoset Addendum to SOAP Messages with Attachmens」という仕様書を公開した。この仕様書は、W3Cに提出されたSOAP Messages with Attachmentsの仕様と互換性を保ちつつ、SOAPメッセージング仕様との親和性を実現するための機能を記述したものだ。

 
 

 INDEX
  [特集]次世代XML Webサービスを試す Part 4
  SOAPメッセージとファイル添付
    1.SOAPメッセージの添付ファイル
    2.WSEとWS-Attachments
    3.DIMEメッセージの解析
  4.ほかのWS-Attachments実装との相互運用
 
 「特集:次世代XML Webサービスを試す」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間