HttpUtil.java 8.59 KB
package com.cjs.cms.util.net;

import java.nio.charset.Charset;
import java.nio.charset.CodingErrorAction;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.config.MessageConstraints;
import org.apache.http.config.SocketConfig;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.web.util.UriTemplate;

import com.cjs.cms.util.lang.JsonUtil;

/**
 * HTTP工具类
 * 
 * @author 仝玉甫
 *
 */
public final class HttpUtil {

    public static final Charset        CHARSET       = Charset.forName("GBK"); // httpclient读取内容时使用的字符集
    private static final int           TIME_OUT      = 5000;
    private static CloseableHttpClient httpClient    = null;
    private static RequestConfig       requestConfig = null;

    static {
        PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager();

        // Create socket configuration
        SocketConfig socketConfig = SocketConfig.custom().setTcpNoDelay(true).build();
        manager.setDefaultSocketConfig(socketConfig);
        //消息限制
        MessageConstraints messageConstraints = MessageConstraints.custom().setMaxHeaderCount(200)
            .setMaxLineLength(2000).build();
        //连接配置
        ConnectionConfig connectionConfig = ConnectionConfig.custom()
            .setMalformedInputAction(CodingErrorAction.IGNORE)
            .setUnmappableInputAction(CodingErrorAction.IGNORE)
            .setMessageConstraints(messageConstraints).setCharset(CHARSET).build();
        manager.setDefaultConnectionConfig(connectionConfig);
        manager.setMaxTotal(200);//连接池最大并发连接数
        manager.setDefaultMaxPerRoute(20);//单路由最大并发数
        httpClient = HttpClients.custom().setConnectionManager(manager).build();

        //请求配置
        requestConfig = RequestConfig.custom().setSocketTimeout(TIME_OUT)
            .setConnectTimeout(TIME_OUT).setConnectionRequestTimeout(TIME_OUT).build();
    }

    /**
     * POST请求
     * @param uri 请求的URI
     * @param params 请求参数
     * @return 远程服务器相应,如果状态不是200,则返回null
     */
    public static String doPost(String uri, Map<String, String> params) throws Exception {
        HttpPost httpPost = new HttpPost(uri);
        CloseableHttpResponse response = null;
        try {
            httpPost.setConfig(requestConfig);
            //绑定到请求 Entry
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            for (Map.Entry<String, String> entry : params.entrySet()) {
                nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
            httpPost.setEntity(new UrlEncodedFormEntity(nvps, CHARSET));
            response = httpClient.execute(httpPost);
            if (response == null || response.getStatusLine().getStatusCode() != 200) {
                return null;
            }
            HttpEntity entity = response.getEntity();
            //使用EntityUtils的toString方法,传递编码,默认编码是ISO-8859-1
            return EntityUtils.toString(entity, getContentCharSet(entity));
        } catch (Exception e) {
            throw e;
        } finally {
            if (response != null) {
                response.close();
            }
            httpPost.releaseConnection();
        }
    }

    /**
     * POST请求
     * @param uri 请求的URI
     * @param params 请求参数
     * @param callback 
     */
    public static String doPost(String uri, Map<String, String> params,
                                HttpClientCallback callback) throws Exception {
        HttpPost httpPost = new HttpPost(uri);
        CloseableHttpResponse response = null;
        try {
            httpPost.setConfig(requestConfig);
            //绑定到请求 Entry
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            for (Map.Entry<String, String> entry : params.entrySet()) {
                nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
            httpPost.setEntity(new UrlEncodedFormEntity(nvps, CHARSET));
            response = httpClient.execute(httpPost);
            return callback.process(response);
        } catch (Exception e) {
            throw e;
        } finally {
            if (response != null) {
                response.close();
            }
            httpPost.releaseConnection();
        }
    }

    /**
     * 使用POST发送JSON格式参数
     * @param uri 请求的URI
     * @param params 请求参数
     * @return 远程服务器相应,如果状态不是200,则返回null
     */
    public static String postJSON(String uri, Object params) throws Exception {
        RequestConfig config = RequestConfig.custom().setSocketTimeout(TIME_OUT)
            .setConnectTimeout(TIME_OUT).build();
        HttpPost httpPost = new HttpPost(uri);
        try {
            httpPost.setHeader("Content-type", "application/json");
            httpPost.setConfig(config);
            StringEntity input = new StringEntity(JsonUtil.toJson(params), CHARSET);
            //input.setContentType("application/json");
            httpPost.setEntity(input);
            HttpResponse response = httpClient.execute(httpPost);
            if (response == null || response.getStatusLine().getStatusCode() != 200) {
                return null;
            }
            HttpEntity entity = response.getEntity();
            //使用EntityUtils的toString方法,传递编码,默认编码是ISO-8859-1
            return EntityUtils.toString(entity, getContentCharSet(entity));
        } catch (Exception e) {
            throw e;
        } finally {
            httpClient.close();
        }
    }

    /**
     * Get请求
     * @param uri 请求的URI
     * @param params URL格式如下:http://xxx?a={a}&b={b}
     * @return 远程服务器相应,如果状态不是200,则返回null
     */
    public static String doGet(String uri, Map<String, String> params) throws Exception {
        HttpGet httpGet = null;
        CloseableHttpResponse response = null;
        try {
            if (params != null) {
                uri = new UriTemplate(uri).expand(params).toString();
            }
            httpGet = new HttpGet(uri);
            httpGet.setConfig(requestConfig);
            response = httpClient.execute(httpGet);
            if (response == null || response.getStatusLine().getStatusCode() != 200) {
                return null;
            }
            HttpEntity entity = response.getEntity();
            //使用EntityUtils的toString方法,传递编码,默认编码是ISO-8859-1
            return EntityUtils.toString(entity, getContentCharSet(entity));
        } catch (Exception e) {
            throw e;
        } finally {
            if (response != null) {
                response.close();
            }
            if (httpGet != null) {
                httpGet.releaseConnection();
            }
        }
    }

    /**获取响应的编码类型,默认为UTF-8*/
    public static String getContentCharSet(final HttpEntity entity) throws ParseException {
        if (entity == null) {
            throw new IllegalArgumentException("HTTP entity may not be null");
        }
        String charset = null;
        if (entity.getContentType() != null) {
            HeaderElement values[] = entity.getContentType().getElements();
            if (values.length > 0) {
                NameValuePair param = values[0].getParameterByName("charset");
                if (param != null) {
                    charset = param.getValue();
                }
            }
        }
        if (StringUtils.isEmpty(charset)) {
            charset = "GBK";
        }
        return charset;
    }

    public interface HttpClientCallback {
        public String process(CloseableHttpResponse response) throws Exception;
    }
}