Exception utilisant HttpRequest.execute (): Utilisation non valide de SingleClientConnManager: connexion toujours alloué

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

Question

J'utilise google-api-client-java-1.2.1 alpha pour exécuter une requête POST, et je obtenir la stacktrace suivante quand j'execute () le HttpRequest.

Il arrive immédiatement après que je surprends et ignorer une erreur 403 d'un précédent à la même URL et RÉUTILISÉS le transport pour la demande ultérieure. (Il est dans une boucle d'insérer plusieurs entrées pour le même flux ATOM).

Y at-il quelque chose que je devrais faire pour « nettoyer » après 403?

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)

Pourquoi est-ce le code ci-dessous me essayer d'acquérir une nouvelle connexion

Était-ce utile?

La solution

Vous devez consommer le corps de la réponse avant de pouvoir réutiliser la connexion à une autre demande. Vous devez non seulement lire l'état de réponse, mais lisez la InputStream de réponse pleinement au dernier octet par lequel vous ignorez les octets de lecture.

Autres conseils

Je faisais face à un problème similaire lors de l'utilisation du HttpClient avec la jetée pour construire un cadre de test. Je devais créer plusieurs demandes au Servelet de mon client, mais il fournissais la même exception lors de l'exécution.

J'ai trouvé une alternative à la http://foo.jasonhudgins.com /2010/03/http-connections-revisited.html

Vous pouvez également utiliser cette méthode suivante pour instancier votre client.

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

Un message d'exception similaire (depuis au moins Apache Commons Jarkata Client HTTP 4.2) est:

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

Cette exception peut se produire lorsque deux ou plusieurs threads interagissent avec un seul org.apache.http.impl.client.DefaultHttpClient.

Comment pouvez-vous faire un exemple 4,2 DefaultHttpClient threadsafe ( threadsafe dans le sens où deux ou plusieurs threads peuvent interagir avec elle sans obtenir au-dessus de message d'erreur)? Fournir DefaultHttpClient avec une ClientConnectionManager mise en commun connexion sous forme de 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);
        }
    }
}

Cette question est souvent posée. La réponse de BalusC est correcte. S'il vous plaît prendre HttpReponseException et appeler HttpResponseException. réponse . ignorer (). Si vous avez besoin de lire le message d'erreur, utilisez la réponse. parseAsString (), d'autre si vous connaissez la réponse type de contenu d'utilisation. de parseAs (MyType.class).

Un simple extrait de code YouTubeSample.java youtube-jsonc-échantillon (bien que généralement vous aurez envie de faire quelque chose de plus intelligent dans une application réelle):

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

La divulgation complète: Je suis propriétaire du google-api-java- projet client .

J'ai eu le même problème avec un JAX-RS (resteasy) objet Response dans mes tests unitaires. Je résolu ce problème avec un appel à response.releaseConnection(); Le releaseConnection () -. La méthode est uniquement sur l'objet de ClientResponse resteasy, donc je devais ajouter un casting de Response à ClientResponse

Essayer cette

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, j'ai le même problème, tous ceux qui solution ne travaille, je l'ai testé sur un périphérique, problème était la date dans l'appareil, il a été à la place 2011 2013, vérifiez également que cela peut aider.

Lire la InputStream comme ceci:

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

consommer juste la réponse comme ci-dessous, qui résoudra le problème

response.getEntity().consumeContent();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top