Аналогичное сообщение об исключении (поскольку, по крайней мере, Apache Jarkata Commons HTTP Client 4.2):
java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated.
Make sure to release the connection before allocating another one.
Это исключение может возникнуть, когда два или более потоков взаимодействуют с одним org.apache.http.impl.client.DefaultHttpClient
.
Как сделать экземпляр 4.2 DefaultHttpClient
поточно-безопасным экземпляром ( threadsafe в том смысле, что два или более потоков могут взаимодействовать с ним без получения сообщения об ошибке выше)? Предоставьте DefaultHttpClient
пул соединений ClientConnectionManager
в виде 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);
}
}
}