2012-03-06 22 views
4

我想通過網絡流發送Java bean實例。我想用JAXB和普通的OutputStream對java實例進行編組/解組,以通過網絡推送它。JAXB通過套接字和流 - 閱讀器塊

的服務器等待解組點,但客戶端已經進一步了很多東西。

服務器:

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停止解組?如果我關閉客戶端輸出流,則消息到達服務器端。

+1

XML讀取器和寫入器是不必要的(您可以使用常規輸出流),但不應該導致任何阻塞問題。請張貼正在流式傳輸的課程。 – Perception 2012-03-06 19:01:08

+0

謝謝,請參閱編輯。這是否可能是解組人員正在等待某種特殊信號來阻止解組? – 2012-03-06 19:27:52

+0

您是否可以修復標題,以便其他人稍後可以找到它? – mindandmedia 2012-03-06 20:22:54

回答

3

我切換到XMLEventWriterXMLEventWriter和有用。我有感覺XMLStreamReader是越野車。它卡在一些skipSpaces()方法。代碼XMLStreamReader看起來好像應該在文檔結束時立即返回。

0

不幸的是,我認爲XML解析器完成(它不放棄,只是因爲它已經收到了XML的「結束」)前等待流的末尾。

一個辦法是把一些流包裝上返回-1所有的XML數據被讀取之後,流套接字的頂部。然而,搞清楚何時達到這一點是不平凡的情況。

另一個選擇是創建自己的XMLEventReader它包裝爲代表的XMLEventReader並接收閉幕XML活動結束後。

This是另一種解決辦法(馬克定製「的流結束」)。

1

這看起來是解組器輸出流語義窒息。我的猜測是,它期望通過以可用長度發信號-1來終止流,並且當它變爲0時試圖永久讀取塊。雖然它看起來有些詭異,但你可以通過使用中間讀者/作者來解決這個問題。

下面是一個例子,根據你的代碼,使用中介串讀/寫:

服務器:

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

謝謝,如果消息對象有一個新行字符的字段,這不會中斷嗎?我認爲在轉換過程中沒有任何東西可以逃脫新行,因爲它們在xml結構中是安全的。 – 2012-03-06 22:37:58

+0

如果您需要支持XML中的多行,那麼在解組之前,您需要在服務器端讀取並連接多行。 – Perception 2012-03-06 23:17:48

+0

「它期望通過用可用長度的信號-1來終止流」。那是什麼意思? – EJP 2012-03-07 01:08:26