2012-03-06 5 views
4

ネットワークストリーム経由でJava Beanインスタンスを送信しようとしています。私は、JAXBと通常のOutputStreamのJavaインスタンスをマーシャリング/アンマーシャリングしてネットワーク上にプッシュしたいと思っています。JAXBのソケットとストリーム - リーダーブロック

サーバは非マーシャルポイントで待機していますが、クライアントはすでにさらにアロケーションしています。

サーバー:

inputStream = new BufferedInputStream(this.socket.getInputStream()); 
outputStream = new BufferedOutputStream(this.socket.getOutputStream()); 
JAXBContext requestContext = JAXBContext.newInstance(this.requestClass); 
Unmarshaller unmarshaller = requestContext.createUnmarshaller(); 
@SuppressWarnings("unchecked") 
K request = (K) unmarshaller.unmarshal(inputStream); //blocks here 
respond(); 

クライアント:

JAXBContext messageContext = JAXBContext.newInstance(message.getClass()); 
Marshaller marshaller = messageContext.createMarshaller(); 
out = new BufferedOutputStream(socket.getOutputStream()); 
marshaller.marshal(message, out); 
out.flush(); 
waitForResponse();// blocks here 

EDIT:私は通常の出力ストリームに切り替えたが、それはまだブロック。アンマーシャリングを停止するようにJAXBに指示するために特別な信号を送信する必要がありますか?クライアント出力ストリームを閉じると、メッセージはサーバー側に到着します。

+1

XMLリーダーとライターは不要です(通常の出力ストリームを使用できます)が、ブロッキングの問題は発生しません。ストリーミング中のクラスを投稿してください。 – Perception

+0

ありがとう、編集を参照してください。 unmarshallerがアンマーシャリングを停止するための特別な信号を待っていることができますか? –

+0

あなたはタイトルplsを修正できますか?他の人はこれを後で見つけるでしょうか? – mindandmedia

答えて

3

私はXMLEventWriterXMLEventWriterに切り替えをし、できます。私は感じているXMLStreamReaderバグです。それはいくつかのskipSpaces()メソッドに固執します。 XMLStreamReaderのコードは、文書の最後が表示されるとすぐに返されるように見えます。

0

残念ながら、私はXMLパーサが終了する前にストリームの終わりを待っていると思います(xmlの "終わり"を受信しただけであきらめない)。

1つのオプションは、すべてのxmlデータが読み込まれた後に-1を返すソケットストリームの上にストリームラッパーを置くことです。しかし、あなたがその時点に達した時を把握することは、些細なことではありません。

別のオプションは、デリゲートXMLEventReaderをラップする独自のXMLEventReaderを作成し、終了xmlイベントが受信された後に終了することです。

Thisは、別の解決策(カスタム「ストリーム終了」マーク)です。

1

unmarshallerがソケット出力ストリームのセマンティクスで窒息しているようです。私の推測では、利用可能な長さのために-1の信号を送ることによってストリームが終了することを期待しており、代わりに0を取得したときに永遠に読み込もうとするブロックであると考えられます。ハッキングしたように見えるかもしれませんが、中間のリーダライタを使用することでこの問題を回避できます。

サーバー:

final BufferedReader socketReader = new BufferedReader(new InputStreamReader(this.socket.getInputStream())); 
final StringReader dataReader = new StringReader(socketReader.readLine()); 

JAXBContext requestContext = JAXBContext.newInstance(this.requestClass); 
Unmarshaller unmarshaller = requestContext.createUnmarshaller(); 
@SuppressWarnings("unchecked") 
K request = (K) unmarshaller.unmarshal(dataReader); 

respond(); 

はクライアント:ここ

は、仲介文字列リーダ/ライタ使用して、あなたのコードに基づいて、一例である

JAXBContext messageContext = JAXBContext.newInstance(message.getClass()); 
Marshaller marshaller = messageContext.createMarshaller(); 
final StringWriter dataWriter = new StringWriter(); 
marshaller.marshal(message, dataWriter); 
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 
out.write(dataWriter.toString()); 
out.newLine(); 
out.flush(); 
waitForResponse(); 
+0

ありがとうございます。メッセージオブジェクトに改行文字のあるフィールドがある場合、これは壊れませんか?私は変換中に何かが新しい行をエスケープするとは思わない。なぜなら、それらはxml構造体で安全だからだ。 –

+0

XMLでマルチラインをサポートする必要がある場合は、アンマーシャリングする前に、サーバー側で複数の行を読み込んで連結する必要があります。 – Perception

+0

"利用可能な長さのために信号-1によってストリームが終了することを期待しています"。どういう意味ですか? – EJP

関連する問題