C#クライアントからTomcatにHTTP(POST)通信しXMLデータを取得する
ひょんなことで、C#.NETで作成したWindowsアプリケーションとTomcat5(Java)で作成したWebアプリケーションとのHTTP通信を行うシステムを作成したので、覚書します。
サーバ側は、テーブル及びビュー単位にSQL抽出クラスを準備して、
各メソッドは、必ずメッセージクラスを介して実行されるように作成していたので、今回の通信は、メッセージクラスを動的に呼び出すだけでできました。※よかったよかった
ですので、Tomcat(Java)側では、クラスとメソッドとフィールドを動的に判断しXMLデータを返すように作ってみました。
おかげで、Strutsの設定も1個だけでした。
今回は、クライアント側のプログラムだけ覚書します。
詳しい方はご指摘お願いしますね(w
なお、気になるサーバ側は次回覚書します。
<クライアント:C#側>
—————————————————————————-
■通信実行を指示するクラス
jp.seemo.xml.msg.XXXMLMsg : XMLデータセット
jp.seemo.xml.XXXMLFacility : 通信クラス
この2つのクラスを使って、サーバのクラスに対してメッセージを投げてみました。
サーバ側では、動的にクラスやメソッドを実行したいので、以下の様に実行してほしい機能を呼び出しました。
<xml_facility_class> : データベースからデータを抽出しXMLデータを生成するクラス
<xml_facility_method> : 実際に呼び出すメソッド
<xml_message> : やり取りするデータを表現する型
private jp.seemo.xml.msg.XXXMLMsg getList()
{
//通信メッセージの作成
jp.seemo.xml.msg.XXXMLMsg inMsg = new jp.seemo.xml.msg.XXXMLMsg();
//通信クラスを生成
jp.seemo.xml.XXXMLFacility xf = new jp.seemo.xml.XXXMLFacility(inMsg);
//通信実行
xf.execute(”<xml_facility_class>”, “<xml_facility_method>”, “<xml_message>”);
//レスポンスデータの取得
jp.seemo.xml.msg.XXXMLMsg bean = (jp.seemo.xml.msg.XXXMLMsg)xf.Items;
return bean;
}
—————————————————————————-
■XML通信を行うアブストラクトクラス
次のアブストラクト・クラスを継承して実際の通信処理を実装してみました。これでいちいち通信ロジックを書かなくてこれ一個でいけますね。
※コード内のTool.showSystemErrorは、システムエラーを簡易処理するメソッドです。
using System;
namespace jp.seemo.xml
{
public abstract class XMLFacility
{
protected System.Data.DataSet _items; //実際のキャリア
protected string class_name; //サーバのクラス名
protected string method_name; //サーバのメソッド名
protected string message_class; //サーバのメッセージ名
public XMLFacility(System.Data.DataSet inMsg)
{
this._items = inMsg; //送り側のメッセージ
}
public XMLFacility()
{}
/// <summary>
/// Java側で動的にクラス・メソッド・メッセージを選択する為に名称をセットしリクエストする
/// </summary>
/// <param name=”class_name”>クラス名</param>
/// <param name=”method_name”>メソッド名</param>
/// <param name=”message_class”>メッセージキャリア名</param>
public void execute(string class_name, string method_name, string message_class)
{
this.class_name = class_name;
this.method_name = method_name;
this.message_class = message_class;
httpRequest(); //実際の通信
}
/// <summary>
/// レスポンスデータを解析し、データをセットします。
/// </summary>
/// <param name=”resStream”></param>
protected void httpResponse(System.Xml.XmlTextReader resStream)
{
// XMLをリード
_items.Clear();
_items.ReadXml(resStream);
}
/// <summary>
/// 要求をPOSTし、結果をサーバから得ます。
/// </summary>
protected void httpRequest()
{
const string methodName = “httpRequest”;
System.IO.Stream reqStream = null;
System.Net.WebResponse res = null;
System.IO.Stream resStream = null;
System.IO.TextReader sr = null;
try
{
//バイト型配列に変換
byte[] postDataBytes = System.Text.Encoding.ASCII.GetBytes(postData());
//Requestの作成
System.Net.WebRequest req = System.Net.WebRequest.Create(”http://localhost:8080/xxxx/xmlf.do”);
req.Method = “POST”;
req.ContentType = “application/x-www-form-urlencoded”;
req.ContentLength = postDataBytes.Length;
reqStream = req.GetRequestStream();
reqStream.Write(postDataBytes, 0, postDataBytes.Length);
reqStream.Close();
//response
res = req.GetResponse();
resStream = res.GetResponseStream();
//受信して表示
sr = new System.IO.StreamReader(resStream, Tool.encode);
System.Xml.XmlTextReader tr = new System.Xml.XmlTextReader(sr);
//TEST
//Console.WriteLine(sr.ReadToEnd());
httpResponse(tr);
}
catch(Exception ex)
{
Tool.showSystemError(”XMLFacility”, methodName, ex);
}
finally
{
try
{
if (sr != null)
{
sr.Close();
}
}
catch(Exception ex)
{
Tool.showSystemError(”XMLFacility”, methodName, ex);
}
try
{
if (reqStream != null)
{
reqStream.Close();
}
}
catch(Exception ex)
{
Tool.showSystemError(”XMLFacility”, methodName, ex);
}
try
{
if (resStream != null)
{
resStream.Close();
}
}
catch(Exception ex)
{
Tool.showSystemError(”XMLFacility”, methodName, ex);
}
try
{
if (res != null)
{
res.Close();
}
}
catch(Exception ex)
{
Tool.showSystemError(”XMLFacility”, methodName, ex);
}
}
}
/// <summary>
/// レスポンスデータ
/// </summary>
public System.Data.DataSet Items
{
get
{
return this._items;
}
}
}
}
—————————————————————————-
■XMLFacility(通信用クラス)を継承して作成したクラス
POSTデータをセットして、送信するクラスを完成させます。
namespace jp.seemo.xml
{
/// <summary>
/// 通信ネタ(POSTデータ)を作成し、通信を行う
/// </summary>
public class XXXXMLFacility : XMLFacility
{
private string postData()
{
msg.XXXMLMsg inMsg = (msg.XXXMLMsg)Items;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
int count = inMsg.row.Count;
sb.Append(”class_name=” + System.Web.HttpUtility.UrlEncode(this.class_name));
sb.Append(”&method_name=” + System.Web.HttpUtility.UrlEncode(this.method_name));
sb.Append(”&message_class=” + System.Web.HttpUtility.UrlEncode(this.message_class));
for (int i=0; i<count; i++)
{
sb.Append(”&user_id=” + System.Web.HttpUtility.UrlEncode(inMsg.row[i].user_id, Tool.encode));
sb.Append(”&password=” + System.Web.HttpUtility.UrlEncode(inMsg.row[i].password, Tool.encode));
}
string mystr = sb.ToString();
return mystr;
}
/// <summary>
/// リクエストメッセージを投入する
/// </summary>
/// <param name=”inMsg”></param>
public XXXXMLFacility(System.Data.DataSet inMsg): base(inMsg)
{}
public XXXXMLFacility(){}
}
}
以上です。