httpclient4 的封裝

支持可配置的連接池, 單例的httpclinet, 更好的response handle


package zhwb.util;

import org.apache.http.HttpHost;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * The type Custom http component.
 *
 * @author jack.zhang
 */
@Component
public class CustomHttpComponent {

    private static final Logger LOG = LoggerFactory.getLogger(CustomHttpComponent.class);

    private static final int MAX_TOTAL = 200;

    private static final int DEFAULT_TIMEOUT = 200;

    private HttpClient httpClient;

    /**
     * Instantiates a new Custom http component.
     * 單個站點最大允許連接:200
     * 單個站點最大允許連接數:200
     * 默認連接超時時間:200ms
     * 默認數據接收超時時間:200ms
     */
    public CustomHttpComponent() {
        PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager();
        connectionManager.setDefaultMaxPerRoute(MAX_TOTAL);
        connectionManager.setMaxTotal(MAX_TOTAL);
        HttpParams httpParams = new BasicHttpParams();
        httpParams.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, DEFAULT_TIMEOUT);
        httpParams.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, DEFAULT_TIMEOUT);
        httpClient = new DefaultHttpClient(connectionManager);
    }

    /**
     * Instantiates a new Custom http component.
     *
     * @param maxPerRoute    單個站點最大允許連接
     * @param maxTotal       單個站點最大允許連接數
     * @param connTimeout    連接超時時間
     * @param soTimeout      數據接收超時時間
     * @param staleConnCheck 是否進行陳舊連接檢查, 如果不開啓, 則啓動陳舊連接關閉線程
     */
    public CustomHttpComponent(int maxPerRoute, int maxTotal, int connTimeout, int soTimeout, boolean staleConnCheck) {
        PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager();
        connectionManager.setDefaultMaxPerRoute(maxPerRoute);
        connectionManager.setMaxTotal(maxTotal);
        HttpParams httpParams = new BasicHttpParams();
        httpParams.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, connTimeout);
        httpParams.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, soTimeout);
        httpParams.setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, staleConnCheck);
        if (!staleConnCheck) {
            new IdleConnectionMonitorThread(connectionManager).start();
        }
        httpClient = new DefaultHttpClient(connectionManager);
    }

    /**
     * Execute t.
     *
     * @param httpHost       the http host
     * @param httpUriRequest the http uri request
     * @param handler        the handler
     * @return the t
     * @throws java.io.IOException the iO exception
     */
    public <T> T execute(HttpHost httpHost, HttpUriRequest httpUriRequest, AbstractResponseHandler<T> handler) throws IOException {
        return httpClient.execute(httpHost, httpUriRequest, handler, new BasicHttpContext());
    }

    /**
     * Execute t.
     *
     * @param httpUriRequest the http uri request
     * @param handler        the handler
     * @return the t
     * @throws java.io.IOException the iO exception
     */
    public <T> T execute(HttpUriRequest httpUriRequest, AbstractResponseHandler<T> handler) throws IOException {
        return httpClient.execute(httpUriRequest, handler, new BasicHttpContext());
    }

    public void shutdown() {
        LOG.debug("Connection manager is shutting down");
        httpClient.getConnectionManager().shutdown();
        LOG.debug("Connection manager shut down");
    }

    /**
     * The type Idle connection monitor thread.
     *
     * @author jack.zhang
     */
    public class IdleConnectionMonitorThread extends Thread {
        private final ClientConnectionManager connMgr;
        private volatile boolean shutdown;

        /**
         * Instantiates a new Idle connection monitor thread.
         *
         * @param connMgr the conn mgr
         */
        public IdleConnectionMonitorThread(ClientConnectionManager connMgr) {
            super();
            this.connMgr = connMgr;
        }

        @Override
        public void run() {
            try {
                while (!shutdown) {
                    synchronized (this) {
                        wait(5000);
                        // Close expired connections
                        connMgr.closeExpiredConnections();
                        // Optionally, close connections
                        // that have been idle longer than 30 sec
                        connMgr.closeIdleConnections(30, TimeUnit.SECONDS);
                    }
                }
            } catch (InterruptedException ex) {
                LOG.warn("exception occur, " + ex.getMessage());
            }
        }

        /**
         * Shutdown void.
         */
        public void shutdown() {
            shutdown = true;
            synchronized (this) {
                notifyAll();
            }
        }
    }
}


繼承 ResponseHandler, 封裝了基本的判斷邏輯
package zhwb.util;


import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.util.EntityUtils;
import org.codehaus.jackson.map.ObjectMapper;

import java.io.IOException;

/**
 * @author jack.zhang
 */
public abstract class AbstractResponseHandler<T> implements ResponseHandler<T> {

    public static final int HTTP_UNSUCCESS_CODE = 300;

    @Override
    public T handleResponse(HttpResponse response) throws IOException {
        StatusLine statusLine = response.getStatusLine();
        HttpEntity entity = response.getEntity();
        if (statusLine.getStatusCode() >= HTTP_UNSUCCESS_CODE) {
            EntityUtils.consume(entity);
            throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
        }
        return handle(entity);
    }

    public abstract T handle(HttpEntity entity) throws IOException;
}


最基本的ResponseHandler

package zhwb.util;

import org.apache.http.HttpEntity;
import org.apache.http.util.EntityUtils;

import java.io.IOException;

/**
 * @author jack.zhang
 */
public class BasicResponseHandler extends AbstractResponseHandler<String> {
    @Override
    public String handle(HttpEntity entity) throws IOException {
        return entity == null ? null : EntityUtils.toString(entity);
    }
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章