2011-07-23 10 views
9

私はクライアントがそれを読んでいるサーバにXMLを送り、そこからPDFを生成してそれをクライアントに返すサーバ - クライアントアーキテクチャを持っています。サーバー側の一方ソケットの入力ストリームを非整列化するとソケットが閉じますか?

JAXBElement<Xml> xml = ... 
Socket sock = ... 
Marshaller marshaller = ... 
marshaller.marshal(xml, sock.getOutputStream()); 
sock.shutdownOuput();  

:クライアント側で

ServerSocket server = ... 
Socket client = server.accept(); 
Unmarshaller unmarshaller = ... 
// client.isClosed() -> false 
JAXBElement<Xml> xml = 
    (JAXBElement<Xml>)) unmarshaller.unmarshall(client.getInputStream()); 
// client.isClosed() -> true 
Pdf pdf = new Pdf(xml); 
client.getOutputStream().write(pdf.toBytes()); 
// "socket is closed" IOException is thrown 

私はアンマーシャリングされない場合は、クライアントのInputStream(サーバー側)だけダミーを送り返しますPDFはすべてスムーズに進みます。だから、私はこのように暗黙のうちに、クライアントSocket私の一日台無しに...これを解決するための

任意のアイデアを閉じ、Unmarshallerは、それが与えられInputStreamを閉じていることを前提とする必要がありますか?

答えて

7

XMLEntityManagerクラスは、InputStreamでcloseを呼び出します。

FilterInputStreamを使用すると、元のストリームのclose()呼び出しを回避できます。

サブクラスFilterInputStreamと空の体でclose()メソッドをオーバーライドします。

public class MyInputStream extends FilterInputStream { 
    public MyInputStream(InputStream in) { 
    super(in); 
    } 

    @Override 
    public void close() { 
    // do nothing 
    } 
} 

が続いて(あなたのアンマーシャリングを変更)(だから、JAXBフレームワークがまだ近い呼び出すに

JAXBElement<Xml> xml = 
    (JAXBElement<Xml>)) unmarshaller.unmarshall(new MyInputStream(client.getInputStream())); 

を呼び出す)にそのストリームは、自分のストリームインスタンスによってフィルタリングされ、ソケットストリームは開いたままです。

+0

おかげで、あなたのソリューションは魅力のように機能します! :) –

6

明示的vanjeようなあなたのコード内でのInputStreamを上書きしたくない場合はお勧め、Apache commons-ioこれをacheive実装提供:

が見取る:

CloseShieldInputStream

+0

非常に良い解決策 –

関連する問題