2013-08-04 67 views
15

我有一個RESTful服務器,它從客戶端獲取HTTP POST輸入以在服務器上投票播放歌曲。我使用Apache HTTPClient作爲客戶端。修復了java.net.SocketTimeoutException:讀取超時

public boolean vote() { 
     HttpClient client = new DefaultHttpClient(getHttpParameters()); 
     HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); // Timeout Limit                    
     HttpResponse response; 
     try { 
      HttpPost post = new HttpPost("http://127.0.0.1:8080/ws/"); 
      StringEntity se = new StringEntity("{ \"song_id\" : \"2\" }"); 
      se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,"application/json")); 
      post.setEntity(se); 
      response = client.execute(post); 
      if (response != null) { 
       InputStream in = response.getEntity().getContent(); // Get the data in the Entity                
       String result = convertStreamToString(in); 
       return true; 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return false; 
     } 
     return false; 
    } 

    public static HttpParams getHttpParameters() { 
     HttpParams httpParameters = new BasicHttpParams(); 
     int timeoutConnection = 30000; 
     HttpConnectionParams.setConnectionTimeout(httpParameters, 
       timeoutConnection); 
     int timeoutSocket = 30000; 
     HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket); 
     return httpParameters; 
    } 

當我點擊繼承投票按鈕,後幾票(如7-8),我得到java.net.SocketTimeoutException: Read timed out例外。 當我查找原因時,我發現這是因爲客戶端在超時期間沒有得到服務器響應。但問題是,當我使用Chrome REST控制檯或JMeter等其他應用程序時,我可以在具有相同參數和路徑的同一臺服務器上投票。我的java代碼有問題嗎?請幫我弄清楚這一點。以下是我的堆棧跟蹤:

java.net.SocketTimeoutException: Read timed out 
    at java.net.SocketInputStream.socketRead0(Native Method) 
    at java.net.SocketInputStream.read(Unknown Source) 
    at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:166) 
    at org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:90) 
    at org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:281) 
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:92) 
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:62) 
    at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:254) 
    at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:289) 
    at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:252) 
    at org.apache.http.impl.conn.ManagedClientConnectionImpl.receiveResponseHeader(ManagedClientConnectionImpl.java:191) 
    at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:300) 
    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:127) 
    at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:715) 
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:520) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784) 
    at notdefault.ServerStuffs.vote(ServerStuffs.java:72) 
    at notdefault.MainClass.actionPerformed(MainClass.java:105) 
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source) 
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source) 
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source) 
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source) 
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source) 
    at java.awt.Component.processMouseEvent(Unknown Source) 
    at javax.swing.JComponent.processMouseEvent(Unknown Source) 
    at java.awt.Component.processEvent(Unknown Source) 
    at java.awt.Container.processEvent(Unknown Source) 
    at java.awt.Component.dispatchEventImpl(Unknown Source) 
    at java.awt.Container.dispatchEventImpl(Unknown Source) 
    at java.awt.Component.dispatchEvent(Unknown Source) 
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) 
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) 
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) 
    at java.awt.Container.dispatchEventImpl(Unknown Source) 
    at java.awt.Window.dispatchEventImpl(Unknown Source) 
    at java.awt.Component.dispatchEvent(Unknown Source) 
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
    at java.awt.EventQueue.access$400(Unknown Source) 
    at java.awt.EventQueue$2.run(Unknown Source) 
    at java.awt.EventQueue$2.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source) 
    at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source) 
    at java.awt.EventQueue$3.run(Unknown Source) 
    at java.awt.EventQueue$3.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source) 
    at java.awt.EventQueue.dispatchEvent(Unknown Source) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
    at java.awt.EventDispatchThread.run(Unknown Source) 
java.net.SocketTimeoutException: Read timed out 
    at java.net.SocketInputStream.socketRead0(Native Method) 
    at java.net.SocketInputStream.read(Unknown Source) 
    at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:166) 
    at org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:90) 
    at org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:281) 
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:92) 
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:62) 
    at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:254) 
    at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:289) 
    at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:252) 
    at org.apache.http.impl.conn.ManagedClientConnectionImpl.receiveResponseHeader(ManagedClientConnectionImpl.java:191) 
    at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:300) 
    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:127) 
    at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:715) 
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:520) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784) 
    at notdefault.ServerStuffs.vote(ServerStuffs.java:72) 
    at notdefault.MainClass.actionPerformed(MainClass.java:105) 
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source) 
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source) 
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source) 
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source) 
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source) 
    at java.awt.Component.processMouseEvent(Unknown Source) 
    at javax.swing.JComponent.processMouseEvent(Unknown Source) 
    at java.awt.Component.processEvent(Unknown Source) 
    at java.awt.Container.processEvent(Unknown Source) 
    at java.awt.Component.dispatchEventImpl(Unknown Source) 
    at java.awt.Container.dispatchEventImpl(Unknown Source) 
    at java.awt.Component.dispatchEvent(Unknown Source) 
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) 
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) 
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) 
    at java.awt.Container.dispatchEventImpl(Unknown Source) 
    at java.awt.Window.dispatchEventImpl(Unknown Source) 
    at java.awt.Component.dispatchEvent(Unknown Source) 
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
    at java.awt.EventQueue.access$400(Unknown Source) 
    at java.awt.EventQueue$2.run(Unknown Source) 
    at java.awt.EventQueue$2.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source) 
    at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source) 
    at java.awt.EventQueue$3.run(Unknown Source) 
    at java.awt.EventQueue$3.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source) 
    at java.awt.EventQueue.dispatchEvent(Unknown Source) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
    at java.awt.EventDispatchThread.run(Unknown Source) 
+1

如果您設置讀取超時,並且您獲得讀取超時而您不希望讀取超時,請增加讀取超時。這只是因爲你要求而發生的。如果你認爲服務器應該比它更快,那就把它拿起來。 – EJP

+2

我試圖增加讀取超時時間,但遲早我遇到了這個問題。實際上,我忘記關閉連接,因此保持所需連接活着並消耗服務器資源。回答@Santosh下面幫了很多。 –

回答

14

下面是調查

  1. 我看你每次投票時,你叫vote方法,它創建了一個新的HTTP連接幾個指針/建議。
  2. 這個可能是個問題。我會建議使用一個HttpClient實例發佈到服務器。這樣它就不會從客戶端創建太多的連接。
  3. 在所有內容結束時,需要關閉HttpClient,因此請撥httpclient.getConnectionManager().shutdown();以釋放連接使用的資源。
+1

謝謝你,你做了我的一天。我在最後關閉了連接,這非常有幫助。 –

2

我不認爲僅僅獲得響應就足夠了。我認爲你需要閱讀它(獲取實體並通過EntityUtils.consume()閱讀它)。

例如(從DOC)

 System.out.println("<< Response: " + response.getStatusLine()); 
    System.out.println(EntityUtils.toString(response.getEntity())); 
+0

其實我有這個,我只是想盡量縮短。我會編輯我的問題。謝謝。 –

相關問題