- PR -

SOAPメッセージの作り方

1
投稿者投稿内容
WT
常連さん
会議室デビュー日: 2004/07/22
投稿数: 29
投稿日時: 2006-12-05 11:14
初めて投稿します。
C#でSOAPクライアントを作成しています。

サーバ:OAS + Axis
クライアント:VS 2003(C#)

上記環境でSOAPメッセージをクライアントから送信し、結果を受信するプログラムをチェックしているのですが、クライアント側でのSOAPメッセージの組み立て方についてイメージができず、御教授願いたいです。

クライアント側の処理は大きく言うと下記のようになります。

1)送信したいデータを一つのクラスに代入します。このクラスはstring型やobject型の変数を持つクラスです。
2)上記1)で作成したクラスを分解して、XMLに変換します。
3)作成したXMLをSOAP通信用のクラスに格納します。上記2)で作成したXMLをUTF-8でエンコードしなおし、Byte[]型として送信用クラスにsetしています。
4)上記3)で作成した送信用クラスをSystem.Web.Services.Protocols.SoapHttpClientProtocol#invoke()を使用して送信します。

私の疑問として・・・
 ・SOAP-EnvelopのHeaderと呼ばれる部分はSoapHttpClientProtocol#invoke()の
  中(.NETの中)で自動的に付与されるのか?
が、分からずにいます。
MSDNオンラインのSoapHttpClientProtocol等も見てみたのですが、明確に「SOAP-EnvelopのHeader部分は自動的に付与される」みたいな記述を見つけられませんでした。
SoapHttpClientProtocol#invoke()でSOAP-Headerは付与されるのでしょうか?


それともう一つ・・・
 ・今回のように、送信するデータ(SOAP-Bodyの部分)を一度、XMLに変換し、
  それを更に送信用のクラスに代入しなおすような実装は一般的なのでしょうか?
XMLに変換せず、直接送信用のクラスにstring型変数やobject型変数を代入して送信する方がシンプルで速いような気がしています。
XMLに変換するのは一般的なのでしょうか?
「そんなのケースバイケース」とは、思うのですが、どなたか同じような実装をした方がいらっしゃれば、許容していいかな・・・と、考えているので、参考までに教えてください。


大雑把な書き方で分かりにくいかとは思いますが、アドバイスの程、お願いします。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2006-12-05 16:20
引用:

WTさんの書き込み (2006-12-05 11:14) より:
それともう一つ・・・
 ・今回のように、送信するデータ(SOAP-Bodyの部分)を一度、XMLに変換し、
  それを更に送信用のクラスに代入しなおすような実装は一般的なのでしょうか?
XMLに変換せず、直接送信用のクラスにstring型変数やobject型変数を代入して送信する方がシンプルで速いような気がしています。
XMLに変換するのは一般的なのでしょうか?



別の言語で送受信可能かどうか、という話ではないのですか?
XMLにしておけば、相手がどの言語でも扱えるよね、という理由ですよね。

# はずしていたら御免なさい
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2006-12-05 19:23
引用:

WTさんの書き込み (2006-12-05 11:14) より:
 ・今回のように、送信するデータ(SOAP-Bodyの部分)を一度、XMLに変換し、
  それを更に送信用のクラスに代入しなおすような実装は一般的なのでしょうか?


よくあることです。ただし、わざわざプログラム内でXMLをテキストにして(ですよね?)
それをバイトストリームで送る、というのは普通はしないと思います。.NETによる
Webサービスの実装はよく知らないのですが、ドキュメント型、あるいはメッセージ型の
送信方法(ようするにXMLメッセージをやりとりする実装)があるのではないでしょうか。

引用:

XMLに変換せず、直接送信用のクラスにstring型変数やobject型変数を代入して送信する方がシンプルで速いような気がしています。


XMLに変換しない、というのはどのようにイメージしていますか?
どちらにしてもSOAPメッセージ上はXMLに変換されるので、速度の問題はないと思います。
また、サーバとクライアントで言語が異なるのでそのままインスタンスデータをやりとり
することはできません。オブジェクトとしてやり取りするのであれば、サーバ側では
それをアンマーシャリング(XMLからオブジェクトに変換)することが必要になります。

引用:

XMLに変換するのは一般的なのでしょうか?
「そんなのケースバイケース」とは、思うのですが、どなたか同じような実装をした方がいらっしゃれば、許容していいかな・・・と、考えているので、参考までに教えてください。


XMLメッセージでやり取りするほうが柔軟性はありますし、言語間の差異は吸収しやすいです。
クラスインスタンスとしてやり取りするほうが、プログラムとしてはわかりやすいです。
その辺のトレードオフではないでしょうか。
WT
常連さん
会議室デビュー日: 2004/07/22
投稿数: 29
投稿日時: 2006-12-05 20:25
nagiseさん、ukさん返信ありがとうございます。

>別の言語で送受信可能かどうか、という話ではないのですか?
>XMLにしておけば、相手がどの言語でも扱えるよね、という理由ですよね。

はい。理由をつけるならば、自分もそう考えています。
今一つ納得行ってないのが何か旨く説明できてないのですが・・・
今回のアプリで作成するSOAP-Envelopの中身は下記のようになっているとイメージしています。

SOAP-Envelope-------------------------------------

| SOAP-Header---------------------------------
| |
| | SOAP-Body-----------------------------
| | |
| | | データのXML---------------------
| | | |<?xml version=\"1.0\" encoding=\"UTF-8\"?>
| | | | <Name>Hoge</Name>
| | | | <Tel>0003154</Tel>
| | | | <LoginTime>20061205</LoginTime>
| | | | ・・・
| | | |------------------------------
| | |------------------------------------
| |------------------------------------------
|------------------------------------------------

上記の「データのXML」内について、全てのelementを一度String(text)化し("<"や">"さえも)文字列として組み立てています。
このようなやり方でやるのであれば、「データのXML」を取っ払って・・・


SOAP-Envelope-------------------------------------

| SOAP-Header---------------------------------
| |
| | SOAP-Body-----------------------------
| | |
| | | <Name>Hoge</Name>
| | | <Tel>0003154</Tel>
| | | <LoginTime>20061205</LoginTime>
| | | ・・・
| | |------------------------------------
| |------------------------------------------
|------------------------------------------------

上記のようにSOAP-Body直下に直接elementを書いて行っても良いのでは?
と、考えていました。

ただ、今、気づいたのですが上記やり方だと、一つのWebServiceの口に対して決まったフォーマットでしかデータのやり取りができず、汎用的ではない・・・かなぁ・・・と、思いました。
「データのXML」を利用していれば、幾つかのWebServiceの口に対して
     受信 → XMLの抽出
位までは共通化できそうですし。



>よくあることです。
>ただし、わざわざプログラム内でXMLをテキストにして(ですよね?)
>それをバイトストリームで送る、というのは普通はしないと思います。

上記理解しました。
(データのXMLを作る事は)よくやる手法なのですね。
参考になりました。



>XMLに変換しない、というのはどのようにイメージしていますか?

説明不足(と、言うか説明が良くない)で、すいません。
先に記述したとおり、「データのXML」を取っ払い、SOAP-Body配下に直接、elementを書いてはどうか?
と、考えていました。
極論すれば<?xml version=\"1.0\" encoding=\"UTF-8\"?>の一行を削除するだけなのですが。



もう一つの質問である「SOAP-EnvelopのHeaderと呼ばれる部分はSoapHttpClientProtocol#invoke()の中(.NETの中)で自動的に付与されるのか?」については、やはり自動で付与されるのでしょうか?
質問ばかりで申し訳ないのですが、ご存知でしたらお教え下さい。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-12-05 21:28
System.Runtime.Serialization.Formatters.Soap.SoapFormatter
System.Runtime.Serialization.Formatters.SoapMessage

wsdl が作られているなら、[Web 参照の追加]

ってことじゃないのかorz
_________________
大ベテラン
会議室デビュー日: 2006/06/28
投稿数: 116
投稿日時: 2006-12-06 00:18
W3Cでの規定です。
http://www.w3.org/TR/soap/

どうやらXML宣言は表現の中に含まれていないです。
私の所有するちょっと古い.NETの教科書では宣言はSOAP-Envelope外(前)に記述されています。
また、この本にはSOAP-Headerについてはまったく記述がないのです。
デフォルトでは付加されないのではないでしょうか?
MSDNサイトを参照するとSoapHeaderクラスの具象クラスで設定するようです。

[ メッセージ編集済み 編集者: 暁 編集日時 2006-12-06 08:13 ]
WT
常連さん
会議室デビュー日: 2004/07/22
投稿数: 29
投稿日時: 2006-12-06 11:25
Jittaさん、暁さん、返信ありがとうございます。

>wsdl が作られているなら、[Web 参照の追加]
>ってことじゃないのかorz

上記、指摘ありがとうございます。
少しずつ整理が付いてきました。
MSDN内でも上記キーワードで検索していると、「ProxyクラスがパラメータをXML要素に割り当て、ネットワーク経由でSOAPメッセージを送信する」役割を担っている事を見つけられました。
今はSOAP-HeaderはProxyクラス内で組み立てられる。と、想像しています。
もうちょっと継続して調べたいと思います。


>どうやらXML宣言は表現の中に含まれていないです。

上記、情報ありがとうございます。
規定がないのであれば「今回のコードも決して変わったコーディングな訳では無い」と考えています。
もう少し、調べてから判断したいと思っていますが。


>MSDNサイトを参照するとSoapHeaderクラスの具象クラスで設定するようです。

ありがとうございます。
自分でも確認したいと思います。


アドバイス、情報、ありがとうございました。
1

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