6

自從早上面對這個奇怪的問題,我正在對一個特定的端點進行REST調用,這個端點在頁面上給出了響應,所以我需要一次又一次地調用直到所有頁面都已完成。我的代碼可以正常工作,直到最後一頁之後,我發出的下一個請求(應該返回一個空白頁)httpClient.execute(httpGet);之後的最後一頁被永久阻止,永遠不會返回或者不會引發任何異常。如果我設置了連接請求超時,那麼最後一次呼叫沒有被阻止,並且沒有通知超時,但我不明白爲什麼最後一次呼叫不起作用如果我從firefox RESTClient進行最後一次呼叫,它的作用是。請幫助。Apache HTTPClient 4.3.3爲GET請求執行方法塊並從不返回

我也嘗試添加不同的日誌級別,如System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");和其他日誌調試,但沒有運氣。

以下是我的代碼。

private static Servers fetchServers(String token,String endpoint) throws Exception{ 
    JsonReader jreader = null; 
    InputStreamReader isr = null; 
    CloseableHttpClient httpClient = null; 
    try{ 
     URI uri = new URI(endpoint); 

     /** accepting all certificates */ 
     httpClient = getSecuredHttpClient(); 

     uri = new URIBuilder(uri) 
       .setParameter("limit", "1")//Page limit, for testing have kept just 1 since i have only 2 records. 
       .build(); 

     HttpGet httpGet = new HttpGet(uri); 

     httpGet.setHeader(HTTP.CONTENT_TYPE, "application/json"); 
     httpGet.setHeader("X-Auth-Token", token); 
     httpGet.setHeader("accept", "application/json"); 
     httpGet.setHeader(HTTP.USER_AGENT, "python-neutronclient"); 

     Servers cloudServers = new Servers(); 
     cloudServers.setServers(new ArrayList<Server>()); 

     boolean nextPage = false; 

     do { 
       HttpResponse resp = httpClient.execute(httpGet);//this is where it gets blocked for last page. 
       if(resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK){ 
        isr = new InputStreamReader(resp.getEntity().getContent()); 
        jreader = new JsonReader(isr); 
        Gson gson = new GsonBuilder().registerTypeAdapter(Address.class, new AddressAdapter()).create(); 

        Servers servers = gson.fromJson(jreader, Servers.class); 
        cloudServers.getServers().addAll(servers.getServers()); 

        if(servers.getServersLinks() == null || servers.getServersLinks().size()==0) 
         nextPage = false; 
        else if(servers.getServersLinks().get(0).getRel().equals("next")) 
         nextPage = true; 

        uri = new URI(servers.getServersLinks().get(0).getHref());//this gives the url for next page. 
        httpGet.setURI(uri); 
       }else{ 
        break; 
       } 
     } while (nextPage); 
     return cloudServers; 
    }catch(Exception e){ 
     throw e; 
    }finally{ 
     if(null != jreader){ 
      jreader.close(); 
     } 
     if(null != isr){ 
      isr.close(); 
     } 
     if(null != httpClient){ 
      httpClient.close(); 
     } 
    } 
} 

任何幫助,非常感謝。

-Regards 威爾

+0

服務器在另一端刷新()流嗎? –

+0

在做的時候,在「httpGet.setURI(uri)」之後嘗試打印URI,然後你知道它在哪裏阻塞的URI。然後嘗試單獨使用該URI執行一個小測試。它仍然掛?你看到它的價值有什麼不尋常的地方嗎? –

+0

@LanceJava不,如果我通過REST客戶端執行相同的分頁,它可以很好地工作。 – willsteel

回答

12

我相當確信你的代碼簡單地泄​​漏,並最終耗盡連接。

do { 
    CloseableHttpResponse resp = httpClient.execute(httpGet); 
    try { 

    // Do what you have to do 
    // but make sure the response gets closed no matter what 
    // even if do not care about its content 

    } finally { 
     resp.close(); 
    }   
} while (nextPage);  
+0

感謝Oleg yup你是對的我會一定要補充一點,但這不是什麼導致這裏的問題,因爲我只做了3頁請求和最後一個請求被阻止。 – willsteel

+2

@willsteel:默認情況下,httpclient每個路由限制有兩個連接。需要3次請求才能耗盡游泳池並使其鎖定;-) – oleg

+0

哇!我明確地不知道每個路由限制的這兩個連接,正如你所建議的,我使用了CloseableHTTPResponse並且它像魅力一樣工作。感謝奧列格:) – willsteel