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

时间:2022-08-26 18:49:30

I'm trying to send java bean instances over a network stream. I want to marshal/unmarshal java instances with JAXB and a normal OutputStream to push it over the network.

我正在尝试通过网络流发送java bean实例。我想用JAXB编组/解组java实例和普通的OutputStream来推送它通过网络。

The servers wait at the unmarshal point but the client is already alot further.

服务器在unmarshal点等待,但客户端已经很多了。

Server:

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();

Client:

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: I switched to a normal output stream but it still blocks. Do I have to send some special signal to tell JAXB to stop unmarshalling? If I close the client output stream the message arrives at the server side.

编辑:我切换到正常输出流但它仍然阻止。我是否必须发送一些特殊信号告诉JAXB停止解组?如果我关闭客户端输出流,则消息到达服务器端。

3 个解决方案

#1


3  

I switched to XMLEventWriter and XMLEventWriter and it works. I've got the feeling XMLStreamReader is buggy. It gets stuck on some skipSpaces() method. The code of XMLStreamReader looks as if it should return as soon as a end of document appears.

我切换到XMLEventWriter和XMLEventWriter,它的工作原理。我感觉XMLStreamReader是错误的。它被卡在一些skipSpaces()方法上。 XMLStreamReader的代码看起来好像应该在文档结尾出现时立即返回。

#2


1  

It would seem that the unmarshaller is choking on socket output stream semantics. My guess would be that it is expecting the stream to be terminated by signalling -1 for the available length, and blocks trying to read forever when it gets 0 instead. Though it may seem hackish, you can get around this problem by using intermediate reader/writers.

似乎unmarshaller正在阻塞套接字输出流语义。我的猜测是,它期望通过信号-1为可用长度终止流,并阻止尝试在它变为0时永远读取。虽然它可能看似hackish,但你可以通过使用中间读者/作者解决这个问题。

Here is an example, based on your code, using intermediary string reader/writer:

以下是基于代码的示例,使用中间字符串读取器/写入器:

Server:

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();

Client:

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();

#3


0  

unfortunately, i think the xml parser waits for end of stream before finishing (it doesn't give up just because it has received the "end" of the xml).

不幸的是,我认为xml解析器在完成之前等待流的结束(它不会因为它已经收到xml的“结束”而放弃)。

one option would be to put some stream wrapper on top of the socket stream which returns -1 after all the xml data has been read. however, figuring out when you have reached that point is a non-trivial situation.

一个选项是将一些流包装器放在套接字流的顶部,在读取所有xml数据后返回-1。然而,弄清楚你何时达到这一点是一个非平凡的情况。

another option would be to create your own XMLEventReader which wraps a delegate XMLEventReader and ends after the closing xml event is received.

另一种选择是创建自己的XMLEventReader,它包装一个委托XMLEventReader,并在收到结束xml事件后结束。

This is another solution (custom "end of stream" marks).

这是另一种解决方案(自定义“流结束”标记)。

#1


3  

I switched to XMLEventWriter and XMLEventWriter and it works. I've got the feeling XMLStreamReader is buggy. It gets stuck on some skipSpaces() method. The code of XMLStreamReader looks as if it should return as soon as a end of document appears.

我切换到XMLEventWriter和XMLEventWriter,它的工作原理。我感觉XMLStreamReader是错误的。它被卡在一些skipSpaces()方法上。 XMLStreamReader的代码看起来好像应该在文档结尾出现时立即返回。

#2


1  

It would seem that the unmarshaller is choking on socket output stream semantics. My guess would be that it is expecting the stream to be terminated by signalling -1 for the available length, and blocks trying to read forever when it gets 0 instead. Though it may seem hackish, you can get around this problem by using intermediate reader/writers.

似乎unmarshaller正在阻塞套接字输出流语义。我的猜测是,它期望通过信号-1为可用长度终止流,并阻止尝试在它变为0时永远读取。虽然它可能看似hackish,但你可以通过使用中间读者/作者解决这个问题。

Here is an example, based on your code, using intermediary string reader/writer:

以下是基于代码的示例,使用中间字符串读取器/写入器:

Server:

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();

Client:

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();

#3


0  

unfortunately, i think the xml parser waits for end of stream before finishing (it doesn't give up just because it has received the "end" of the xml).

不幸的是,我认为xml解析器在完成之前等待流的结束(它不会因为它已经收到xml的“结束”而放弃)。

one option would be to put some stream wrapper on top of the socket stream which returns -1 after all the xml data has been read. however, figuring out when you have reached that point is a non-trivial situation.

一个选项是将一些流包装器放在套接字流的顶部,在读取所有xml数据后返回-1。然而,弄清楚你何时达到这一点是一个非平凡的情况。

another option would be to create your own XMLEventReader which wraps a delegate XMLEventReader and ends after the closing xml event is received.

另一种选择是创建自己的XMLEventReader,它包装一个委托XMLEventReader,并在收到结束xml事件后结束。

This is another solution (custom "end of stream" marks).

这是另一种解决方案(自定义“流结束”标记)。