2013-12-11 117 views
1

我有一段代碼從Servlet請求的輸入流中讀取POST數據。我正在使用Java nio來讀取數據。從Servlet請求輸入流讀取時的套接字超時

對於大多數情況和常規數據,代碼工作得很好。但是在某些情況下數據很大(content length = 600000),Channel的讀取方法似乎失敗,並出現套接字超時錯誤。此外,這似乎只發生在IE 9,它與Firefox和Chrome工作正常。

在調查這個問題時,我發現,在使用IE時,發佈數據似乎比其他瀏覽器需要更長的時間才能閱讀。因此,我在代碼和代碼開始正常工作以前也使用了一個Thread.sleep(400)

我不想在這段代碼之前進行睡眠,一次只是一種解決方法,而不是一個正確的解決方案,其次,沒有正確的睡眠時間,因爲如果數據增加,400可能還不夠。

有沒有一種方法可以告訴頻道不要超時或完全刪除超時?

下面正在使用代碼,

ReadableByteChannel channel = Channels.newChannel(inputStream); 
byte[] postData = new byte[contentLength]; 
ByteBuffer buf = ByteBuffer.allocateDirect(contentLength); 
int numRead = 0; 
int counter = 0; 
while (numRead >= 0) { 
    buf.rewind(); 
    numRead = channel.read(buf); 
    buf.rewind(); 
    for (int i = 0; i < numRead; i++) { 
     postData[counter++] = buf.get(); 
    } 
} 
return postData; 

InputStream的是直接通過request.getInputStream()和內容長度是經由request.getContentLength()。

使用的容器是嵌入模式下的Tomcat 7.0.42。

+0

發佈您的代碼,那麼也許我們可以幫助您! – isnot2bad

+0

是否從您的客戶端代碼發出POST請求?如果是這樣,它是什麼技術?請參閱以下帖子瞭解java中的http請求超時:http://stackoverflow.com/questions/1414795/how-to-specify-http-request-timeout-parameter-on-java-servlet-container。 –

+0

@MarkTielemans,是的POST是從客戶端代碼。使用SmartGWT(一個javascript工具包)。您提到的鏈接似乎提供了有關客戶端超時的詳細信息。而在我的情況下,錯誤似乎源於服務器放棄,而不是等待。 – Vicky

回答

0

因爲我找不到適合此問題的任何適當解決方案。我繼續我現有的工作,即睡眠一段時間。但我的問題是我睡了多長時間,因爲我需要睡更多的數據。而且沒有正確的方法知道,因爲我無法從內容長度中推導出任何公式,所以睡眠時間是隨機的。

因此,我可以應用的下一個最好的事情是,我發現了套接字超時異常,並且至少在我知道需要的最短時間內睡眠了400毫秒。然後再次嘗試,在放棄之前設置3次重試的邏輯。迄今爲止,已經有效,用於增加數據量。

0

您的閱讀超時時間太短。增加它。

但我會拋出這個NIO代碼,並直接從輸入流中讀取。使用DataInputStream.readFully()它是一行代碼。不管怎樣,你的NIO代碼都是這樣做的,但是以一種非常迂迴的方式加入了幾個額外的層。

+0

如何才能增加獲取輸入流的servlet的讀取超時?我希望它需要一定量的重新實現具體的客戶端? –

+0

@Szymon這確實提供了一個問題的答案,它不包含或甚至包含批評或澄清請求。你在說胡話。 – EJP

+0

@ AndersR.Bystrup請求的讀取超時將在某個配置中爲您的未命名的Servlet容器設置,或者在未聲明的代碼中將輸入流映射到通道中。 – EJP

0

如果您可以閱讀內容長度標題,您可以根據它增加休眠時間。這應該至少讓你的代碼在不同的場景中起作用。這當然是一種解決方法,但它似乎是一個穩定的解決方案。或者,您可以set the socket timeout wait to a higher number。然而,這個改變將會用於你的所有servlet,並且不太靈活。

+0

您提到的線程談論了Apache JK連接器到tomcat的設置。 – Vicky

相關問題