- PR -

JavaとC#の間でオブジェクトをやりとりする方法

投稿者投稿内容
ひらふ
会議室デビュー日: 2008/05/30
投稿数: 5
投稿日時: 2008-05-30 19:00
はじめまして。

サーバをjava、クライアントをC#としてソケット通信を行うプログラムを作成しています。
ソケットは問題なくつながります。

オブジェクトをjavaではObjectOutputStreamやObjectInputStreamを使い、
C#ではBinaryFormatterを用いてシリアライズしているのですが、
送った先でうまくデシリアライズできません。
javaでjava.io.Externalizable を実装して、
writeExternalやreadExternalを使えばなんとかなりそうな気はするのですが、
具体的な方法がわかりません。
SOAPの様な技術を新たに利用せず、java(もしくはC#)の技術だけでjavaとC#の間でオブジェクトのやり取りを行う方法はあるのでしょうか?

何かアドバイスをいただければ幸いです。
よろしくお願いします。
わたなべ
大ベテラン
会議室デビュー日: 2007/12/09
投稿数: 123
お住まい・勤務地: 札幌
投稿日時: 2008-05-30 19:41
相手が読める形に変換して送れば良いだけです。

ObjectOutputStreamで変換してしまうとJavaでないと解釈できません。
(どのようにバイナリ化されるかを解析すれば可能、やる気があれば)
したがって、オブジェクトをプレインテキストに変換して送信し、受信側でそれを解析してオブジェクトに変換するやり方が簡単でしょう。
構造化されたオブジェクトをテキストにするのでXMLが最適ですね。
また、テキストにすればソケット通信を使わなくとも、HTTP等で通信を行う事も可能です
Java僧
ぬし
会議室デビュー日: 2003/11/06
投稿数: 261
投稿日時: 2008-05-30 22:08
SOAPは何でダメなんでしょう?
性能かな?
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2008-05-31 00:45
他言語間でメッセージやオブジェクトをやりとりするために、
フォーマットと呼ばれる概念があります。

わたなべさんも仰るように、テキストで表現して、
読み込む側、書き出す側でフォーマットに基づいた、
オブジェクトへの変換をする必要があるでしょう。

そのうちの1つがSOAPになるわけです。
ひらふ
会議室デビュー日: 2008/05/30
投稿数: 5
投稿日時: 2008-05-31 09:44
わたなべ様、Java僧様、かつのり様返信ありがとうございます。

オブジェクトをプレーンテキストに変換し、
それぞれにフォーマットに基づいたオブジェクトに変換する、
ということの意味は理解できますし納得できるのですが、
具体的なやり方がわかりません。
簡単なものでいいので具体例か、
もしくはこういったことを勉強するのに良い資料がありましたら紹介していただけないでしょうか

SOAPの様な技術を利用しないと言うことについては、
私がそういう条件でプログラムの作成をしているというだけで、
性能などに問題があるというわけではありません。
SOAPがだめなのではなく、
java(もしくはC#)の技術だけでなんとかしたいということです。
わかりにくい表現ですみませんでした。
ひろ@ya
大ベテラン
会議室デビュー日: 2006/02/23
投稿数: 168
投稿日時: 2008-05-31 10:08
「Java XML シリアライズ」で検索
ぴあちゃん
ぬし
会議室デビュー日: 2008/02/07
投稿数: 287
投稿日時: 2008-05-31 20:27
エンティティクラスのXMLをJavaの文法表現で作成する。
以下のXMLは、Test クラスで パブリックプロパティ A,B,C 3つ持つ。
<class path="jp.co.xxx.Test">
<property name="A" type="Integer">12345</property>
<property name="B" type="String">12345</property>
<property name="C" type="Double">3.14</property>
</class>

Velocity で Java 用エンティティクラスのテンプレートと C# 用エンティティクラス
のテンプレートを作成する。詳細は、VelocityのHPでダウンロードして見て下さい。

テンプレートを通して得られるJava/C# エンティティクラスは以下のようになります。
コード:
[C#]
namespace Jp.Co.Xxx
{
   public class Test
   {
       private int _A;
       private string _B;
       private double _C;
       //A,B,C の プロパティがここに記述さてれてるけど省略
       public string ToString()
       {
          //ここで 上記XMLを出力する文字列を生成して返す。
       }
   }
}  



コード:
[Java]
package jp.co.xxx;
public class Test {
   private int _A;
   private String _B;
   private double _C;
   //A,B,C 用 GETTER/SETTER がテンプレートで出力されているが省略
   public String toString() {
      //XML 文字列を作成して返す。
   }
}



この2つのクラスがそれぞれ C#/Java 用の ソケット通信の受信したXMLを解析して
データを格納するクラスになり、それぞれの toString() / ToString() で得られる
XMLが送信用XMLテキストになります。

で、XMLはJavaのクラス、データ型で表現している関係上、C#側にJava文法とC#文法
を照らし合わせるためのマップを置いておきます。
Javaでは、String ですが、C# だと string ですからね。大文字小文字区別するので、
基本データ型はロジックで組んでも問題ないと思いますが。

これらが作成できたら、今度はXMLを解析してクラスオブジェクトを作成する処理を
C#/Javaに設置します。
Java は、Proxy クラス関連の資料を漁って見てください。
C# は、RealProxy クラス関連の資料を漁ってみてください。

XML の <class> タグから エンティティクラスオブジェクトを作成し、
<property> タグの name と type と 値から、Java なら、"set" を前に付加して
name の先頭文字を大文字にした名前を作成して、値をセットします。
C# も Java 同様、GETTER/SETTER でやるなら、上記のようにしたらいいですね。
C# の場合は、getXxx や setXxx はあまりやらないのでそこらへんは適当に
やって下さい。

エンティティクラスとかめんどくさい、ってなら、とりあえず、XMLだけ作って
それを送受信して、XmlReader とか使って読むとか。

# 私には敷居が高そうです。とか言って諦めないで下さいね。
# そんなに難しくありませんから。
ひらふ
会議室デビュー日: 2008/05/30
投稿数: 5
投稿日時: 2008-06-01 23:30
返信が遅くなってすみません。
ひろ@ya様、ぴあちゃん様返信ありがとうございます。

お二人が教えてくれた内容を参考にして、
自分なりに勉強してみようと思います。

問題解決に協力してくださった皆様、
本当にありがとうございました。

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