wake-up-neo.com

Ausnahme bei Verwendung von HttpRequest.execute (): Ungültige Verwendung von SingleClientConnManager: Verbindung weiterhin zugewiesen

Ich verwende google-api-client-Java 1.2.1-alpha, um eine POST -Anforderung auszuführen, und erhalte den folgenden stacktrace, wenn ich () die HttpRequest-Datei ausführte. 

Es geschieht unmittelbar nachdem ich einen 403-Fehler von einem vorherigen POST an dieselbe URL abfangen und ignorieren und den Transport für die nachfolgende Anforderung erneut verwendet habe. (Es ist in einer Schleife, die mehrere Einträge in den gleichen ATOM-Feed einfügt).

Gibt es etwas, was ich tun sollte, um nach einem 403 aufzuräumen?

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 der Code unter mir versuchen, eine neue -Verbindung zu erhalten?

78
David Bullock

Sie müssen den Antworttext verwenden, bevor Sie die Verbindung für eine andere Anforderung wiederverwenden können. Sie sollten nicht nur den Antwortstatus lesen, sondern die Antwort InputStream vollständig bis zum letzten Byte lesen, wobei Sie die gelesenen Bytes einfach ignorieren.

80
BalusC

Bei der Verwendung des HttpClient mit Jetty zum Erstellen eines Testframeworks war ich mit einem ähnlichen Problem konfrontiert. Ich musste mehrere Anfragen von meinem Client an das Servelet erstellen, aber bei der Ausführung gab es dieselbe Ausnahme.

Ich habe eine Alternative gefunden unter http://foo.jasonhudgins.com/2010/03/http-connections-revisited.html

Sie können diese Methode auch verwenden, um Ihren Client 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;
}
42
Ujjwal Wadhawan

Eine ähnliche Ausnahmemeldung (da zumindest 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 mit einem einzelnen org.Apache.http.impl.client.DefaultHttpClient interagieren.

Wie können Sie eine 4.2 DefaultHttpClient-Instanz threadsafe ( threadsafe in dem Sinne, dass zwei oder mehr Threads damit interagieren können, ohne dass die obige Fehlermeldung angezeigt wird)? Stellen Sie DefaultHttpClient ein Verbindungspooling ClientConnectionManager in Form von org.Apache.http.impl.conn.PoolingClientConnectionManager bereit!

/* 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);
        }
    }
}
9
Abdull

Dies ist eine häufig gestellte Frage. Die Antwort von BalusC ist korrekt. Bitte fangen Sie HttpReponseException ab und rufen Sie HttpResponseException . response . ignore () auf. Wenn Sie die Fehlermeldung lesen müssen, verwenden Sie die Antwort . parseAsString (), wenn Sie den Antwortinhaltstyp nicht kennen. Andernfalls, wenn Sie den Inhaltstyp kennen, verwenden Sie die Antwort . parseAs (MyType.class ).

Ein einfaches Code-Snippet aus YouTubeSample.Java in youtube-jsonc-sample (in der Regel möchten Sie jedoch in einer echten Anwendung etwas intelligenter machen):

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

Vollständige Offenlegung: Ich bin Eigentümer des Projekts google-api-Java-client .

8
Yaniv Inbar

Ich hatte das gleiche Problem mit einem Jax-Rs (Resteasy) Response -Objekt in meinen Unit-Tests. Ich löste dies mit einem Aufruf von response.releaseConnection(); The releaseConnection () - Methode ist nur für das resteasy ClientResponse -Objekt, daher musste ich eine Besetzung von Response zu ClientResponse hinzufügen.

3
markus

verwenden Sie einfach die unten stehende Antwort, um das Problem zu lösen

response.getEntity().consumeContent();
0
Mohammed Rafeeq

Versuche dies

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 ein ähnliches Problem, alle diese Lösung funktioniert nicht. Ich habe ein Gerät getestet. 

0
marko

Lesen Sie den InputStream so:

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() + "" );
    }
}
0
lucasddaniel