6

Angesichts dieser seltsamen Problem seit dem Morgen, mache ich einen REST-Aufruf an einen bestimmten Endpunkt, der Antworten in den Seiten gibt, so dass ich immer wieder Anrufe machen muss Alle Seiten sind fertig. Mein Code funktioniert gut und dandy bis zur letzten Seite nach der letzten Seite die nächste Anfrage, die ich mache (die eine leere Seite zurückgeben sollte) von httpClient.execute(httpGet); ist dauerhaft blockiert und kommt nie zurück oder keiner wirft eine Ausnahme. Wenn ich das Zeitlimit für die Verbindungsanforderung festlege, wird der letzte Anruf nicht blockiert und die Zeitüberschreitung schlägt fehl, aber ich verstehe nicht, warum der letzte Anruf nicht funktioniert Wenn ich denselben letzten Anruf von Firefox RESTClient mache funktioniert es. Freundlich helfen.Apache HTTPClient 4.3.3 execute Methode für eine GET Anfrage Blöcke und gibt nie

Ich habe auch versucht, verschiedene Protokollebenen wie System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog"); und andere Protokolle zu debuggen, aber kein Glück.

Unten ist mein Code.

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

Jede Hilfe wird sehr geschätzt.

-Regards Will

+0

Hat der Server am anderen Ende gespült() den Stream? –

+0

in der tun, während nach "httpGet.setURI (uri)" versuchen, den URI zu drucken und dann wissen Sie den URI, wo es blockiert. Versuchen Sie dann, einen kleinen Test mit diesem URI alleine auszuführen. hängt es noch? Siehst du etwas Ungewöhnliches an seinem Wert? –

+0

@LanceJava Nein, wenn ich dieselbe Paginierung über REST-Client mache, funktioniert es einwandfrei. – willsteel

Antwort

12

Ich bin ziemlich sicher, dass Ihr Code einfach leckt und schließlich läuft aus Verbindungen.

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

Danke Oleg Yup Sie haben Recht, ich werde sicherstellen, dass hinzufügen, aber das ist nicht, was verursacht das Problem hier, da ich nur 3 Seitenanforderungen machen und die letzte Anfrage blockiert. – willsteel

+2

@willsteel: httpclient hat standardmäßig zwei Verbindungen pro Routenlimit. Es braucht 3 Anfragen, um den Pool zu erschöpfen und ihn zu blockieren ;-) – oleg

+0

wow! Ich wusste definitiv nicht über diese zwei Verbindungen pro Route Grenze, wie Sie vorgeschlagen, CloseableHTTPResponse und es funktioniert wie Charme. Danke Oleg :) – willsteel