Eccezione utilizzando HttpRequest.execute (): Utilizzo non valido di SingleClientConnManager: collegamento ancora assegnato

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

Domanda

sto usando google-api-client-java 1.2.1-alpha per eseguire una richiesta POST, e sto ottenendo il seguente stacktrace quando eseguo () il HttpRequest.

Succede subito dopo mi cattura e ignorare un errore 403 da un post precedente per lo stesso URL, e ri-usato il trasporto per la successiva richiesta. (È in un ciclo di inserire più voci allo stesso feed ATOM).

C'è qualcosa che dovrei fare a 'clean up' dopo un 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)

Perché il codice sotto di me cercare di acquisire un nuovo di connessione?

È stato utile?

Soluzione

È necessario consumare il corpo della risposta prima di poter riutilizzare la connessione per un'altra richiesta. Non si deve leggere solo lo stato della risposta, ma leggere il InputStream risposta pienamente all'ultimo byte per cui è semplicemente ignorare i byte di lettura.

Altri suggerimenti

stavo affrontando un problema simile quando si utilizza il HttpClient con molo per costruire un quadro di prova. Ho dovuto creare più richieste al Servelet dal mio cliente, ma stava dando la stessa eccezione quando viene eseguito.

Ho trovato un'alternativa a http://foo.jasonhudgins.com /2010/03/http-connections-revisited.html

È inoltre possibile utilizzare questo metodo seguente per creare un'istanza di vostro cliente.

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 messaggio di eccezione simile (almeno dal Apache Commons Jarkata HTTP client 4.2) è il seguente:

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

Questa eccezione può accadere quando due o più fili interagire con un singolo org.apache.http.impl.client.DefaultHttpClient.

Come si può fare un 4,2 DefaultHttpClient esempio threadsafe ( threadsafe , nel senso che due o più thread possono interagire con esso senza ottenere sopra messaggio di errore)? Fornire DefaultHttpClient con una ClientConnectionManager collegamento-pooling, sotto forma di 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);
        }
    }
}

Questa è una domanda ricorrente. La risposta di BalusC è corretta. Si prega di cattura HttpReponseException , e chiamare HttpResponseException. risposta . ignorano (). Se avete bisogno di leggere il messaggio di errore, la risposta l'uso. parseAsString () se non si conosce il tipo di contenuto della risposta, altrimenti se si conosce la risposta tipo di fruizione dei contenuti. parseAs (MyType.class).

Un codice semplice frammento YouTubeSample.java in youtube-jsonc-campione (anche se di solito si vuole fare qualcosa di più intelligente in un'applicazione reale):

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

Full disclosure: io sono un proprietario del google-api-Java- progetto client .

Ho avuto lo stesso problema con un JAX-RS (RESTEasy) oggetto Response nel mio test di unità. Ho risolto questo con una chiamata a response.releaseConnection(); Il releaseConnection () -. Metodo è solo sull'oggetto RESTEasy ClientResponse, così ho dovuto aggiungere un cast da Response a ClientResponse

Prova questo

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, ho problema simile, tutti coloro che non la soluzione di lavoro, ho testato su un device, problema era data nel dispositivo, è stato 2011, invece del 2013, di controllare anche questo può aiutare.

Leggi l'InputStream in questo modo:

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

solo consumare la risposta come qui di seguito, che risolverà il problema

response.getEntity().consumeContent();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top