- PR -

.NET⇔Axis間のSOAPアタッチメントの受信に失敗する

1
投稿者投稿内容
Sola
会議室デビュー日: 2005/08/25
投稿数: 4
投稿日時: 2006-04-05 15:16
初めて投稿いたします。
.NET⇔Axis間のSOAPアタッチメント通信について、質問させてください。

○開発環境

 ≪サーバ≫
  JDK 1.4.2_10、Tomcat 5.0.30、eclipse 3.1 + WTP 1.0.1(Axisは1.2.1)
 ≪クライアント≫
 ・Axis
  JDK 1.4.2_10、Tomcat 5.0.30、eclipse 3.1 + WTP 1.0.1(Axisは1.2.1)
 ・.NET
  Visual Studio .NET 2003(言語はC#を使用)、WTP 2.0 SP3


○現在の状況

SOAPアタッチメント(DIME)を使用したファイル送受信プログラムを作成しています。
サーバはAxisを使用、クライアントはAxisと.NET(WTP)の両方の使用を想定しています。
現在、以下の機能について動作確認が完了しています。
・Axisクライアント⇔Axisサーバ間:ファイル送受信
・.NETクライアント⇔Axisサーバ間:ファイル送信(クラ→サバ方向)


○問題点

.NETクライアントを使用してファイル受信プログラム(クラ←サバ方向)を
実行したところ、.NETのWebサービス呼出し行で以下のExceptionが発生しました。

【エラーメッセージ】
-------------------------------------------------------------------
System.Xml.XmlException: ルート レベルのデータが無効です。 行 1、位置 1 です。
at System.Xml.XmlTextReader.ParseRoot()
at System.Xml.XmlTextReader.Read()
at System.Xml.XmlReader.MoveToContent()
at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at AttachTestServiceClient.WebReference.AttachBeanServiceWse.getData(String str, String saveDir) in d:/work/ms_soapattachment/attachtestserviceclient/web references/webreference/reference.cs:line 80
at AttachTestServiceClient.Form1.button2_Click(Object sender, EventArgs e) in d:/work/ms_soapattachment/attachtestserviceclient/form1.cs:line 226
-------------------------------------------------------------------
どうやら、サーバからのレスポンスメッセージが不正なため、読み取れないようです。
しかし、Javaクライアントから同様のリクエストを送った場合は正常に処理されるので、
サーバプログラム側の問題ではない気がしています。
試しにHTTP送受信メッセージをキャプチャしたところ、以下のようになっていました。

【リクエストヘッダ】

・Axisクライアント⇔Axisサーバの場合
-------------------------------------------------------------------
POST http://localhost:8080/AttachTestService/services/AttachBean HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.2.1
Host: localhost:8080
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Content-Length: 481
(以下略)
-------------------------------------------------------------------
・.NETクライアント⇔Axisサーバの場合
-------------------------------------------------------------------
POST /AttachTestService/services/AttachBean HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 1.1.4322.2032)
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Content-Length: 1339
Expect: 100-continue
Connection: Keep-Alive
Host: 10.90.154.26:8080
(以下略)
-------------------------------------------------------------------
まず、Axisクライアントの場合にはヘッダに「application/dime」という記述がありますが
.NETクライアントの場合にはそのような記述が見当たりません。
ちなみに、同じ.NETクライアントでも、クラ→サバ方向のアップデート要求の際には
リクエストヘッダに「Content-Type: application/dime」との記述がありました。

【レスポンスヘッダ】

・Axisクライアント⇔Axisサーバの場合
-------------------------------------------------------------------
HTTP/1.1 200 OK
Content-Type: multipart/related; type="text/xml"; start="<581443F8B5DE7664961893D418C53250>"; boundary="----=_Part_9_24845668.1144117190453"
Date: Tue, 04 Apr 2006 02:19:50 GMT
Server: Apache-Coyote/1.1
Proxy-Connection: close
Connection: close


------=_Part_9_24845668.1144117190453
(以下略)
-------------------------------------------------------------------
・.NETクライアント⇔Axisサーバの場合
-------------------------------------------------------------------
HTTP/1.1 200 OK
Content-Type: multipart/related; type="text/xml"; start="<E375B951CB5F4E4A47308B9D0BBAA7CD>"; boundary="----=_Part_10_16412836.1144117309593"
Transfer-Encoding: chunked
Date: Tue, 04 Apr 2006 02:21:49 GMT
Server: Apache-Coyote/1.1

26b ←★不正なコード?★

------=_Part_10_16412836.1144117309593
(以下略)
-------------------------------------------------------------------
.NETクライアントのヘッダとボディの間に「26b」というコードが記述されています。
(値はその時により変化します)
XMLExceptionは、この値を参照することにより起こったのではないかと推測されます。


おそらく、クライアントからリクエストを送る際に、DIMEメッセージであることを
明記していない(=通常のSOAPメッセージとして送付している?)ため、サーバから
返されたDIMEメッセージを正しく解釈することができずにエラーになっているのでは
ないかと思っています。
しかし、上記原因に対する対処方法が分からず、困っています。

それとも、他に原因があるのでしょうか?

過去に同様のプログラムを作られた経験がある方がいらっしゃいましたら
お知恵を貸していただければ幸いです。


○参考にしたURL(@IT以外)
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/dnwse/html/wsedime.asp
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2006-04-06 12:41
まず双方の違いとして気になるのは、.NET側のレスポンスがChunkedエンコーディングされて
おり、Axis側はそうではない、ということです。おそらく、Axis側がHTTP1.0でリクエストを
送っているために、HTTP1.1でサポートされたChunkedエンコーディングを解釈できないものと
してレスポンスを返しているのだと思います。

.NET側でChunkedエンコーディングされたレスポンスの解釈に問題や制限がないかどうか
調べてみてはどうでしょうか。また、HTTPのバージョンを指定できるのであれば、1.0に
してみてどうなるかを確認してみてください。
Sola
会議室デビュー日: 2005/08/25
投稿数: 4
投稿日時: 2006-04-06 13:28
>ukさま

書込みありがとうございます。

> まず双方の違いとして気になるのは、.NET側のレスポンスがChunkedエンコーディングされて
> おり、Axis側はそうではない、ということです。おそらく、Axis側がHTTP1.0でリクエストを
> 送っているために、HTTP1.1でサポートされたChunkedエンコーディングを解釈できないものと
> してレスポンスを返しているのだと思います。

ご指摘の件につきまして、Axisクラ⇔Axisサバの場合は、確かにリクエストをHTTP1.0で送っています。
(同じAxisを利用しているにもかかわらずAxisサーバのレスポンスがHTTP1.1なのが謎?ですが…)
しかし、この場合は正常にファイルを受信できているので、問題があるようには思えません。
一方、今回問題となっている通信(.NETクラ⇔Axisサバ)では、リクエスト/レスポンスともに
HTTP1.1で通信が行われているようです。
ですので、HTTPバージョンの相違が原因ではないのでないか、と個人的には思っております。
#おこがましくて申し訳ありません

> .NET側でChunkedエンコーディングされたレスポンスの解釈に問題や制限がないかどうか
> 調べてみてはどうでしょうか。また、HTTPのバージョンを指定できるのであれば、1.0に
> してみてどうなるかを確認してみてください。

アドバイスありがとうございます。
こちらにつきましても調査・試行してみたいと思います。
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2006-04-06 16:02
あー、そもそもレスポンスがDIMEで送られてないのですね。普通に実装してしまうとAxisでは
MIMEフォーマットで送ってしまうために、.NET側が認識できないようですね。

ネットを見ても、サーバ側から添付ファイルを送るサンプルってあまり見当らないのですが、
サーバ側はどのように実装しているのでしょうか。
Sola
会議室デビュー日: 2005/08/25
投稿数: 4
投稿日時: 2006-04-06 16:58
>ukさま
書込みありがとうございます。

> 普通に実装してしまうとAxisでは
> MIMEフォーマットで送ってしまうために、.NET側が認識できないようですね。

そうなのですね!不勉強にして全く知りませんでした;;
SwAはマイクロソフト未サポートですし、どうりで認識できないはずですね(;´Д`)

> ネットを見ても、サーバ側から添付ファイルを送るサンプルってあまり見当らないのですが、
> サーバ側はどのように実装しているのでしょうか。

サーバ側(Axis)のコードを以下に示します。
Axisクライアント⇔Axisサーバの環境で動作確認済みです。
コード内★印で示しているように、一応setProperty()を使ってヘッダにDIMEを
設定している…つもりなのですが、あまり意味を成していないようです(;´Д`)

【サーバ側コード】
--------------------------------------------------------------------------
/** ダウンロード用ファイル置き場 */
public static final String downloadDir = "D:\\hoge\\download\\";

/**
* 引数で与えられた名前のファイルをアタッチメント送信
*/
public String getData(String str) {
 
  String filename = "";
  String retStr = "success";
 
  try {
    if(str.lastIndexOf("\\") != -1) {
      // ファイル名のみ抽出
      filename = str.substring(str.lastIndexOf("\\"));
    } else {
      filename = str;
    }
   
    // 現在のレスポンスメッセージ情報を取得する
    MessageContext ctx = MessageContext.getCurrentContext();
    Message msg = new Message(ctx.getResponseMessage().getSOAPEnvelope());

    // ファイルが存在するか確認
    File f = new File(downloadDir + filename);
    if(f.exists()) {     
      // 添付ファイルデータをアタッチメントとして追加
      AttachmentPart ap = new AttachmentPart(new DataHandler(
          new FileDataSource(downloadDir + filename)));
      ap.setContentType("image");
      msg.addAttachmentPart(ap);
     
      // 添付ファイル情報をレスポンスメッセージに設定
      MessageContext.getCurrentContext().setResponseMessage(msg);
      // HTTPヘッダにDIMEを設定(?)…★
      MessageContext.getCurrentContext().setProperty(
        "attachment_encapsulation_format", "axis.attachment.style.dime");
    }

  } catch (Exception e) {
    e.printStackTrace();
    retStr = "failed";
  }   
  return retStr;
}
--------------------------------------------------------------------------

ちなみに、Axisクライアント版のソースでは、クライアントに
------
call.setProperty(
  Call.ATTACHMENT_ENCAPSULATION_FORMAT,
  Call.ATTACHMENT_ENCAPSULATION_FORMAT_DIME);
------
と記述しているのですが、この行をコメントアウトしても、HTTPヘッダにはきちんと
「application/dime」が付いていました。どこか内部で設定しているっぽいですね…

#Java版では「Accept」ヘッダに「application/dime」があるのに対して
#.NET版では「Content-Type」ヘッダに「application/dime」があるのも気になります。仕様かな…
Sola
会議室デビュー日: 2005/08/25
投稿数: 4
投稿日時: 2006-04-07 10:51
>ukさま

経過報告です。
各条件のリクエスト/レスポンスメッセージを改めて見直してみました。

これまで、Axisクライアントとの通信はDIMEで行われていると思い込んでいましたが
Acceptヘッダには「application/soap+xml, application/dime, multipart/related, text/*」
って書いてあるし、よく見るとレスポンスメッセージにはしっかり「multipart/related」とありますね…
思い切りMIMEじゃないか!(;´Д`)

また、.NETクライアントからのリクエストにはAcceptヘッダが含まれていないため
AxisサーバはデフォルトのMIMEフォーマットでレスポンスを返している可能性が高いですね。

まずは、Axisクライアント⇔Axisサーバ間でDIMEを使用した通信を実装し、その後で
.NETクライアントとの通信について再試行してみたいと思います。
#.NETクライアントからのリクエスト時ににAcceptヘッダで「application/dime」を指定すれば
#うまくいくのではないか?と思っています

丁寧にアドバイスいただき、本当にありがとうございました。
状況が進んだら、随時こちらに書き込んでいきたいと思います。

[ メッセージ編集済み 編集者: Sola 編集日時 2006-04-07 10:55 ]

[ メッセージ編集済み 編集者: Sola 編集日時 2006-04-07 10:56 ]
1

スキルアップ/キャリアアップ(JOB@IT)