我正在尝试通过网络流发送java bean实例。我希望使用JAXB
和普通OutputStream
编组/解组java实例,以便将其推送到网络上。
服务器在unmarshal点等待,但客户端已经进一步。
服务器:
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
编辑:我切换到普通输出流但仍然阻止。我是否必须发送一些特殊信号告诉JAXB停止解组?如果我关闭客户端输出流,则消息到达服务器端。
答案 0 :(得分:3)
我切换到XMLEventWriter
和XMLEventWriter
并且它有效。我有种感觉XMLStreamReader
是错误的。它被卡在某些skipSpaces()
方法上。 XMLStreamReader
的代码看起来好像应该在文档结束时立即返回。
答案 1 :(得分:1)
似乎unmarshaller正在阻塞套接字输出流语义。我的猜测是,它期望通过信号-1为可用长度终止流,并阻止尝试在它变为0时永远读取。虽然它可能看起来像hackish,但你可以通过使用中间读者/作者解决这个问题。
以下是基于代码的示例,使用中间字符串读取器/写入器:
服务器:
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();
答案 2 :(得分:0)
不幸的是,我认为xml解析器在完成之前等待流的结束(它不会因为它已经收到xml的“结束”而放弃)。
一个选项是将一些流包装器放在套接字流的顶部,在读取所有xml数据后返回-1。然而,弄清楚你何时达到这一点是一件非常重要的事情。
另一种选择是创建自己的XMLEventReader,它包装一个委托XMLEventReader,并在收到结束xml事件后结束。
This是另一种解决方案(自定义“流结束”标记)。