Excepción mediante HttpRequest.execute (): Uso no válido de SingleClientConnManager: conexión todavía asignado

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

Pregunta

Estoy usando google-api-cliente-java 1.2.1-alfa para ejecutar una solicitud POST, y estoy recibiendo el siguiente StackTrace cuando ejecuto () la HttpRequest.

Esto ocurre inmediatamente después cojo e ignorar un error de 403 de una entrada anterior a la misma URL, y reutilizado para el transporte de la solicitud posterior. (Está en un bucle de inserción de múltiples entradas a la misma alimentación ATOM).

¿Hay algo que debería estar haciendo a 'la limpieza' después de 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)

¿Por qué el código debajo de mí estar tratando de adquirir un nueva conexión?

¿Fue útil?

Solución

Hay que consumir el cuerpo de la respuesta, antes de usar la conexión para otra petición. Usted no sólo debe leer el estado de respuesta, pero leer la respuesta InputStream totalmente hasta el último byte por el que usted simplemente ignora los bytes de lectura.

Otros consejos

Yo estaba frente a un problema similar cuando se utiliza el HttpClient con embarcadero para construir un marco de prueba. Tenía que crear varias peticiones al Servelet de mi cliente, pero estaba dando la misma excepción cuando se ejecuta.

He encontrado una alternativa en http://foo.jasonhudgins.com /2010/03/http-connections-revisited.html

También puede utilizar este método siguiente para crear instancias de su 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;
}

A mensaje de excepción similar (por lo menos desde Apache Jarkata Commons HTTP Client 4.2) es:

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

Esta excepción puede ocurrir cuando dos o más hilos interactuar con un solo org.apache.http.impl.client.DefaultHttpClient.

¿Cómo se puede hacer un ejemplo para las hebras 4.2 DefaultHttpClient ( multi-hilo en el sentido de que dos o más hilos pueden interactuar con él sin que por encima de mensaje de error)? Proporcionar DefaultHttpClient con un ClientConnectionManager conexión de la puesta en común en forma 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);
        }
    }
}

Esta es una pregunta frecuente. La respuesta de BalusC es correcta. Por favor captura HttpReponseException , y llamar a HttpResponseException. respuesta. ignoran (). Si es necesario leer el mensaje de error, la respuesta uso. parseAsString () si no se conoce el tipo de contenido de la respuesta, de lo contrario si lo hace saber el contenido de la respuesta tipo de uso. parseAs (MyType.class).

Un simple fragmento de código de YouTubeSample.java en youtube-jsonc-muestra (aunque por lo general usted querrá hacer algo más inteligente en una aplicación real):

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

La revelación completa: Soy propietario de la google-api-java- proyecto de cliente .

Yo tenía el mismo problema con un JAX-RS (resteasy) Response objeto en mis pruebas de unidad. He resuelto esto con una llamada a response.releaseConnection(); El releaseConnection () -. Método sólo en el objeto resteasy ClientResponse, por lo que he tenido que añadir un elenco de Response a ClientResponse

Probar

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

Está bien, tengo problema similar, todos los que no la solución de trabajo, he probado en algún dispositivo, el problema era la fecha en el dispositivo, que era 2011 en lugar de 2013, también comprobar esto puede ayudar.

Lea el InputStream como esto:

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

acaba de consumir la respuesta como la de abajo, que va a resolver el problema

response.getEntity().consumeContent();
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top