JAXB通过套接字和流 - 读取器块

时间:2012-03-06 18:38:06

标签: java xml sockets networking jaxb

我正在尝试通过网络流发送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停止解组?如果我关闭客户端输出流,则消息到达服务器端。

3 个答案:

答案 0 :(得分:3)

我切换到XMLEventWriterXMLEventWriter并且它有效。我有种感觉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是另一种解决方案(自定义“流结束”标记)。