Make sure to release the connection before allocating another one

自从HttpClient升级到HttpComponent后,HttpMethod提供的方法releaseConnection()就被丢弃了。转而改成另外相对麻烦点的维护一个连接池的处理方式。

When you replace Apache Commons HttpClient with Apache HttpComponents.if you haven’t release connection in your codes, you may found exception traces like:

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)
 But HttpComponents doesn’t provide method like void org.apache.commons.httpclient.HttpMethod.releaseConnection().

It provides another method to do this work. And it’s more complex then before. Sample codes I wrote below:

public class Test {
    public static void main(String[] args) throws Exception {
        System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire", "debug");
        System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.commons.httpclient", "debug");
        System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
        System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true");
        System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http", "debug");
 
        HttpParams httpParams = new BasicHttpParams();
        httpParams.setIntParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 20);
        SchemeRegistry schreg = new SchemeRegistry();
        schreg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        schreg.register(new Scheme("https", PlainSocketFactory.getSocketFactory(), 443));
        ThreadSafeClientConnManager connManager = new ThreadSafeClientConnManager(httpParams, schreg);
//        connManager.setMaxTotal(20);
         
        DefaultHttpClient client = new DefaultHttpClient(connManager, httpParams);
        String url = "http://www.google.com/";
        HttpGet get = new HttpGet(url);
        sendRequest(get, client);
        System.out.println("------------------2------------------");
        sendRequest(get, client);
        System.out.println("------------------3------------------");
        sendRequest(get, client);
        System.out.println("------------------4------------------");
        sendRequest(get, client);
        System.out.println("------------------5------------------");
        sendRequest(get, client);
    }
 
    private static void sendRequest(HttpGet get, DefaultHttpClient client) throws InterruptedException {
        HttpResponse resp = null;
        try {
            resp = client.execute(get);
            // get response content here
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                resp.getEntity().getContent().close(); //!!!IMPORTANT
            } catch (Exception e) {
                // go to hell
            }
        }
    }
}
 Here are some notes:
  1. HC4.1 may deprecated some methods/properties.
  2. DON’T FORGET TO CLOSE THE RESPONSE STREAM
  3. 转自:http://blog.blacklee.net/tech/707-release-connection-in-apache-httpcomponents

相关推荐