- PR -

C#で作成したWebServiceをJavaから呼び出す方法について

1
投稿者投稿内容
とら
ベテラン
会議室デビュー日: 2006/10/04
投稿数: 54
投稿日時: 2007-10-05 12:46
C#でWebServiceを作成し、これをWindowsアプリケーション(C#)から呼び出す
方法は、判るのですが、これをJavaから呼び出すときの方法が判りません。

Javaから呼び出すことを前提とした場合、WebServiceのパラメータにDataSetは
使用しない方が良いということは、知っているのですが、そのままXMLを構築
すれば、出来なくも無いというような意見も見受けられたので、以下のような
構成での呼び出しテストを行っています。

入力及び出力のパラメータはどちらもDataSetとする。
DataSet内には、1つのDataTableが存在し、これに対するDataRowは1行のみ。
項目は、文字列項目が1つのみとし、null値等の考慮は行わない。

要するに、文字列を1つ引き渡すのに、DataSetの中に入れた場合どうすれば
良いかについて検討している状況です。

まず、出来ている内容を提示します。

以下に示すのは、WebServiceの記述です。

[WebMethod]
public DataSet TestMethod(DataSet InputDS)
{
string InputFld;
//入力パラメータの取り出し
InputFld = InputDS.Tables["InputTB01"].Rows[0]["InputFld"].ToString();

//出力用DataSetの作成
DataSet OutputDS = new DataSet();
OutputDS.DataSetName = "OutputDS";

DataTable OutputTB01 = new DataTable();
OutputTB01.TableName = "OutputTB01";
OutputDS.Tables.Add(OutputTB01);

DataColumn OutputFld = new DataColumn();
OutputFld.DataType = Type.GetType("System.String");
OutputFld.ColumnName = "OutputFld";
OutputTB01.Columns.Add(OutputFld);

DataRow OutputRow = OutputTB01.NewRow();
OutputRow["OutputFld"] = DateTime.Now.ToString();
OutputTB01.Rows.Add(OutputRow);
return OutputDS;
}

これを、Windowsアプリケーションから呼び出しているのが、
以下のコードです。

DataSet InputDS = new DataSet();
InputDS.DataSetName = "InputDS";
DataTable InputTB01 = new DataTable();
InputTB01.TableName = "InputTB01";
InputDS.Tables.Add(InputTB01);
DataColumn InputFld = new DataColumn();
InputFld.DataType = Type.GetType("System.String");
InputFld.ColumnName = "InputFld";
InputTB01.Columns.Add(InputFld);
DataRow InputRow = InputTB01.NewRow();
InputRow["InputFld"] = "SampleData";
InputTB01.Rows.Add(InputRow);

localhost.TestWS myTestWS = new localhost.TestWS();
DataSet OutputDS = myTestWS.TestMethod(InputDS);
string OutputFld;
OutputFld = (string)OutputDS.Tables["OutputTB01"].Rows[0]["OutputFld"];
MessageBox.Show(OutputFld);

これに関しては問題なく動いています。

さて、Javaから呼び出す部分についてですが、Axisを使用して、
WSDL2Javaでプロキシクラスを生成して、それを呼ぶクラスを以下のように
実装しました。

//WebService呼出生成
TestWSLocator myLocator = new TestWSLocator();
TestWSSoap myService = myLocator.getTestWSSoap();
//入力パラメータ用DataSet作成
TestMethodInputDS myInputDS = new TestMethodInputDS();
//====この部分でどうしたら良いかが判りません====//

//出力パラメータ用DataSet定義
TestMethodResponseTestMethodResult myOutputDataSet;
//WebService呼出
myOutputDataSet = myService.testMethod(myInputDS);
//出力用DataSetの取り出し
Document myXmlDocument = myOutputDataSet.get_any()[1].getAsDocument();
//変数値の取り出し
String Field01;
NodeList DataTableList = myXmlDocument.getElementsByTagName("OutputFld");
Node DataTable = DataTableList.item(0);
Field01 = DataTable.getFirstChild().getNodeValue();

当然、このまま実行すると、サーバー(C#)で入力データセットに
アクセスする部分で、例外が発生しますが、その部分をコメントアウト
すると、出力パラメータの内容をJava側で取り出す部分は思ったように
動いています。

多分、XMLを構築して、起動すれば何とかなりそうな気がしているのですが、
方法が思いつきません。

何か、ご存知の方は、アドバイスお願いできませんでしょうか?
宜しくお願いします。
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2007-10-05 15:42
仰る通り、DataSet を使おうが何しようが、流れるデータは XML なのでそれを解釈する方が努力すれば良いことになります。

この例の場合、クライアント(Java)はサーバ(.NET)から取得した DataSet を生の XML データと解釈するように努力しています。

しかし、サーバ(.NET)の方は、受け取った XML を兎に角 DataSet に押し込む事しかしようとしていませんよね。となると、クライアント(Java)の方が「DataSet に変換できる XML」を送ってやるしかないわけです。

DataSet に変換できる XML は、DataSet がどういう XML を入力として受付けるのかを知らなければなりません。DataSet の出力を解釈したのと逆の手順を行えば良いのでしょうけど、スキーマも何もないのでつらいですね。

多分、解決策としてマシなのは型付データセットを公開し、WSDL に情報を付加してあげる事でしょう。そうすれば、クライアントも何をデータとして送ればよいのかが明確になるのではないでしょうか。
_________________
囚人のジレンマな日々
1

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