Ausnahme unter Verwendung HttpRequest.execute (): Ungültige Verwendung von SingleClientConnManager: Verbindung noch zugeteilt

StackOverflow https://stackoverflow.com/questions/4612573

Frage

Ich bin mit google-api-Client-Java 1.2.1-alpha eine POST-Anforderung auszuführen, und mir die folgenden Stacktrace bekommen, wenn ich () die Httprequest ausführen.

Es kommt sofort, nachdem ich einen 403-Fehler von einem frühen Post auf die gleiche URL fangen und ignorieren, und den Transport für die nachfolgende Anforderung wiederverwendet. (Es ist in einer Schleife mehr Einträge zum gleichen ATOM-Feed einfügen).

Gibt es etwas, das ich soll nach einem 403?

zu ‚bereinigen‘ tun
Exception in thread "main" java.lang.IllegalStateException: Invalid use of SingleClientConnManager: connection still allocated.
Make sure to release the connection before allocating another one.
    at org.apache.http.impl.conn.SingleClientConnManager.getConnection(SingleClientConnManager.java:199)
    at org.apache.http.impl.conn.SingleClientConnManager$1.getConnection(SingleClientConnManager.java:173)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:390)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)
    at com.google.api.client.apache.ApacheHttpRequest.execute(ApacheHttpRequest.java:47)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:207)
    at au.com.machaira.pss.gape.RedirectHandler.execute(RedirectHandler.java:38)
    at au.com.machaira.pss.gape.ss.model.records.TableEntry.executeModification(TableEntry.java:81)

Warum sollte unter mir den Code versuchen, eine neue Verbindung zu erwerben?

War es hilfreich?

Lösung

Sie müssen den Antworttext verbrauchen, bevor Sie die Verbindung für eine andere Anforderung wiederverwenden können. Sie sollten nicht nur den Antwortstatus lesen, aber die Antwort InputStream voll auf das letzte Byte gelesen, wobei Sie nur das gelesenen Bytes ignorieren.

Andere Tipps

Ich war mit Blick auf ein ähnliches Problem, wenn den Httpclient mit Jetty mit einem Test-Framework zu bauen. Ich musste mehrere Anfragen an den Servelet von meinem Klienten schaffen, aber es gab die gleiche Ausnahme, wenn sie ausgeführt.

ich eine Alternative fand unter http://foo.jasonhudgins.com /2010/03/http-connections-revisited.html

Sie können auch diese folgende Methode verwenden, um Ihre Kunden zu instanziieren.

public static DefaultHttpClient getThreadSafeClient()  {

    DefaultHttpClient client = new DefaultHttpClient();
    ClientConnectionManager mgr = client.getConnectionManager();
    HttpParams params = client.getParams();
    client = new DefaultHttpClient(new ThreadSafeClientConnManager(params, 

            mgr.getSchemeRegistry()), params);
    return client;
}

Eine ähnliche Meldung Ausnahme (seit mindestens Apache Jarkata Commons HTTP Client 4.2) ist:

java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated. Make sure to release the connection before allocating another one.

Diese Ausnahme kann auftreten, wenn zwei oder mehr Threads interact mit einem einzigen org.apache.http.impl.client.DefaultHttpClient.

Wie können Sie eine 4.2 DefaultHttpClient Instanz THREAD ( THREAD in dem Sinne, dass zwei oder mehr Threads mit ihm, ohne sich über Fehlermeldung in Wechselwirkung treten können)? Geben Sie DefaultHttpClient mit einem Anschluss-Pooling ClientConnectionManager in Form von org.apache.http.impl.conn.PoolingClientConnectionManager!

/* using
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.2.2</version>
    </dependency>
*/

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.impl.conn.SchemeRegistryFactory;
import org.apache.http.params.HttpParams;
import org.apache.http.client.methods.HttpGet;

public class MyComponent {

    private HttpClient client;

    {
        PoolingClientConnectionManager conMan = new PoolingClientConnectionManager( SchemeRegistryFactory.createDefault() );
        conMan.setMaxTotal(200);
        conMan.setDefaultMaxPerRoute(200);

        client = new DefaultHttpClient(conMan);

        //The following parameter configurations are not
        //neccessary for this example, but they show how
        //to further tweak the HttpClient
        HttpParams params = client.getParams();
        HttpConnectionParams.setConnectionTimeout(params, 20000);
        HttpConnectionParams.setSoTimeout(params, 15000);
    }


    //This method can be called concurrently by several threads
    private InputStream getResource(String uri) {
        try {
            HttpGet method = new HttpGet(uri);
            HttpResponse httpResponse = client.execute(method);
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            InputStream is = null;
            if (HttpStatus.SC_OK == statusCode) {
                logger.debug("200 OK Amazon request");
                is = httpResponse.getEntity().getContent();
            } else {
                logger.debug("Something went wrong, statusCode is {}",
                        statusCode);
                 EntityUtils.consume(httpResponse.getEntity());
            }
            return is;
        } catch (Exception e) {
            logger.error("Something went terribly wrong", e);
            throw new RuntimeException(e);
        }
    }
}

Dies ist eine häufig gestellte Frage. BalusC Antwort ist richtig. Bitte fangen HttpReponseException und rufen HttpResponseException. Antwort . ignorieren (). Wenn Sie die Fehlermeldung, die Verwendung Antwort zu lesen. parseAs (MyType.class).

Ein einfacher Code-Schnipsel aus YouTubeSample.java in youtube-jsonc-Probe (obwohl in der Regel sollten Sie etwas schlauer in einer realen Anwendung tun):

  } catch (HttpResponseException e) {
    System.err.println(e.response.parseAsString());
  }

Vollständige Offenlegung: Ich bin ein Besitzer der google-api-Java- Client Projekt.

Ich hatte das gleiche Problem mit einem JAX-RS (Resteasy) Response Objekt in meinen Unit-Tests. Ich löste dies mit einem Aufruf an response.releaseConnection(); Die releaseConnection (.) - Methode ist nur auf dem Resteasy ClientResponse Objekt, so dass ich eine Besetzung von Response zu ClientResponse hinzuzufügen hatte

Versuchen Sie diese

HttpResponse response = Client.execute(httpGet);
response.getEntity().consumeContent();
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
        //task
    Log.i("Connection", "OK");
    }else{
     Log.i("Connection", "Down");
    }

Ok, ich habe ähnliches Problem, all jene Lösung nicht arbeiten, ich auf einem Gerät getestet, Problem war Datum im Gerät, war es 2011 statt 2013, überprüfen Sie auch diese helfen kann.

Lesen Sie die Input wie folgt aus:

if( response.getStatusLine().getStatusCode() == 200 ) {
    HttpEntity entity = response.getEntity();
    InputStream content = entity.getContent();
    try {
        sb = new StringBuilder();
        BufferedReader bufferedReader = new BufferedReader( new InputStreamReader( content ), 8 );
        String line;
        while( ( line = bufferedReader.readLine() ) != null ) {
            sb.append( line );
        }
        bufferedReader.close();
        content.close();
    } catch( Exception ex ) {
        Log.e( "statusCode", ex.getMessage() + "" );
    }
}

verbrauchen nur die Antwort wie unten, dass das Thema

löst
response.getEntity().consumeContent();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top