我有一个服务器 - 客户端架构,客户端将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,那么一切都顺利进行。所以,我必须假设Unmarshaller
关闭了InputStream
,因此隐含关闭客户Socket
毁了我的一天......
有任何关于解决这个问题的想法吗?
答案 0 :(得分:8)
类XMLEntityManager在InputStream上调用close。
您可以使用FilterInputStream来避免对基础流进行close()调用。
Subclass FilterInputStream并使用空体覆盖close()方法:
public class MyInputStream extends FilterInputStream {
public MyInputStream(InputStream in) {
super(in);
}
@Override
public void close() {
// do nothing
}
}
然后将你的unmarshall()调用更改为
JAXBElement<Xml> xml =
(JAXBElement<Xml>)) unmarshaller.unmarshall(new MyInputStream(client.getInputStream()));
因此JAXB框架仍然在流上调用close(),但它现在由您自己的流实例过滤掉,并且套接字流保持打开状态。
答案 1 :(得分:7)