All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.rt.core.util.HttpUtil Maven / Gradle / Ivy

The newest version!
package com.rt.core.util;

import com.json.JSONArray;
import com.json.JSONObject;
import com.rt.core.beans.IOCallback;
import com.rt.core.beans.UrlFile;
import com.rt.core.util.RTUtil;
import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.config.RequestConfig.Builder;
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.client.utils.URIBuilder;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.ByteArrayBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class HttpUtil {

    /**
     * 连接池最大线程数
     */
    private static final int MAX_THREAD = 300;
    /**
     * 每Route最大线程数
     */
    private static final int MAX_THREAD_PER_ROUTE = 150;
    /**
     * 默认统一超时时间
     */
    private static final int MAX_TIMEOUT = 10000;

    /**
     * 闲置时间
     */
    public static final int MAX_IDLE_TIMEOUT = 3000;

    /**
     * User-Agents
     */
    // private static final String UA_ORIGIN = "Apache-HttpClient/4.5.2";
    private static final String UA_FIREFOX = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:53.0) Gecko/20100101 Firefox/53.0";
    private static final String UA = UA_FIREFOX;

    /**
     * 默认编码
     */
    public static final String DEFAULT_CHARSET = "UTF-8";

    /**
     * 连接池
     */
    private static PoolingHttpClientConnectionManager connectionManager;

    /** 空闲链接监控线程 */
    // private static IdleConnectionMonitorThread idleConnectionMonitorThread;

    static {
        connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(MAX_THREAD);
        connectionManager.setDefaultMaxPerRoute(MAX_THREAD_PER_ROUTE);

        // idleConnectionMonitorThread = new IdleConnectionMonitorThread(
        // connectionManager);
        // idleConnectionMonitorThread.start();
        // try {
        // idleConnectionMonitorThread.join(1000);
        // } catch (InterruptedException e) {
        // e.printStackTrace();
        // }
    }

    /**
     * 关闭空闲链接监控线程
     */
    // public static void shutdownIdleConnectionMonitorThread() {
    // idleConnectionMonitorThread.shutdown();
    // }

    /**
     * GET请求,返回字符串 HTTPS请求通过url以https开头来激活
     *
     * @param url     url
     * @param params  参数
     * @param charset 编码
     * @return 响应字符串
     * @throws Exception Exception
     */
    public static String doGet4String(String url, Map headers,
                                      Map params, String charset, int timeout, boolean checkSsl)
            throws Exception {
        if (RTUtil.isEmpty(url)) {
            return null;
        }
        if (headers == null) {
            headers = new HashMap<>();
        }
        if (params == null) {
            params = new HashMap<>();
        }
        if (RTUtil.isEmpty(charset)) {
            charset = DEFAULT_CHARSET;
        }

        byte[] resultBytes = doGet4ByteArray(url, headers, params, charset, timeout, checkSsl);
        return new String(resultBytes, Charset.forName(charset));
    }

    /**
     * GET请求,返回byte数组 HTTPS请求通过url以https开头来激活
     *
     * @param url     url
     * @param params  参数
     * @param charset 编码
     * @return 响应byte数组
     * @throws Exception Exception
     */
    public static byte[] doGet4ByteArray(String url,
                                         Map headers, Map params,
                                         String charset, int timeout, boolean checkSsl) throws Exception {
        if (RTUtil.isEmpty(url)) {
            return null;
        }
        if (headers == null) {
            headers = new HashMap<>();
        }
        if (params == null) {
            params = new HashMap<>();
        }
        if (RTUtil.isEmpty(charset)) {
            charset = DEFAULT_CHARSET;
        }

        byte[] result = null;

        List pairList = param2PairList(params);

        CloseableHttpClient httpclient = buildHTTPClient(url, checkSsl);

        URIBuilder URIBuilder = new URIBuilder(url);
        URIBuilder.setCharset(Charset.forName(charset));
        if (pairList.size() > 0) {
            URIBuilder.addParameters(pairList);
        }
        URI uri = URIBuilder.build();
        HttpGet httpGet = new HttpGet(uri);

        httpGet.setConfig(buildRequestConfig(timeout));

        for (String hkey : headers.keySet()) {
            httpGet.setHeader(hkey, headers.get(hkey));
        }

        CloseableHttpResponse response = httpclient.execute(httpGet);
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            result = EntityUtils.toByteArray(entity);
        }

        EntityUtils.consume(entity);

        return result;
    }

    /**
     * POST请求,返回字符串
     *
     * @param url
     * @param headers
     * @param params
     * @param charset
     * @param timeout
     * @return String
     * @throws Exception
     */
    public static String doPost4String(String url, Map headers,
                                       Map params, String charset, int timeout, boolean checkSsl)
            throws Exception {
        if (RTUtil.isEmpty(url)) {
            return null;
        }
        if (headers == null) {
            headers = new HashMap<>();
        }
        if (params == null) {
            params = new HashMap<>();
        }
        if (RTUtil.isEmpty(charset)) {
            charset = DEFAULT_CHARSET;
        }

        List pairList = param2PairList(params);

        HttpPost httpPost = new HttpPost(url);
        httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset
                .forName(charset)));

        return sendPost4String(url, httpPost, headers, charset, timeout, checkSsl);
    }

    /**
     * POST请求,返回byte数组
     *
     * @param url
     * @param headers
     * @param params
     * @param charset
     * @param timeout
     * @return byte[]
     * @throws Exception
     */
    public static byte[] doPost4ByteArray(String url,
                                          Map headers, Map params,
                                          String charset, int timeout, boolean checkSsl) throws Exception {
        if (RTUtil.isEmpty(url)) {
            return null;
        }
        if (headers == null) {
            headers = new HashMap<>();
        }
        if (params == null) {
            params = new HashMap<>();
        }
        if (RTUtil.isEmpty(charset)) {
            charset = DEFAULT_CHARSET;
        }

        List pairList = param2PairList(params);

        HttpPost httpPost = new HttpPost(url);
        httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset
                .forName(charset)));

        return doPost(url, httpPost, headers, timeout, checkSsl);
    }

    /**
     * 文件上传POST请求
     *
     * @param url     url
     * @param params  参数
     * @param charset 编码
     * @return 响应字符串
     * @throws Exception Exception
     */
    public static String doMultipartPost(String url,
                                         Map headers, Map params,
                                         String charset, int timeout, boolean checkSsl) throws Exception {
        if (RTUtil.isEmpty(url)) {
            return null;
        }
        if (headers == null) {
            headers = new HashMap<>();
        }
        if (params == null) {
            params = new HashMap<>();
        }
        if (RTUtil.isEmpty(charset)) {
            charset = DEFAULT_CHARSET;
        }

        HttpEntity entity = buildMultipartEntity(params, charset);

        HttpPost httpPost = new HttpPost(url);
        httpPost.setEntity(entity);

        return sendPost4String(url, httpPost, headers, charset, timeout, checkSsl);
    }

    /**
     * POST请求,发送字符串,返回字符串
     *
     * @param url
     * @param headers
     * @param str
     * @param charset
     * @param timeout
     * @param contentType
     * @return String
     * @throws Exception
     */
    public static String doPostString4String(String url,
                                             Map headers, String str, String charset,
                                             int timeout, boolean checkSsl, String contentType) throws Exception {
        if (RTUtil.isEmpty(url)) {
            return null;
        }
        if (headers == null) {
            headers = new HashMap<>();
        }
        if (RTUtil.isEmpty(charset)) {
            charset = DEFAULT_CHARSET;
        }

        HttpPost httpPost = new HttpPost(url);
        StringEntity stringEntity = new StringEntity(str, charset);
        if (RTUtil.isNotEmpty(contentType)) {
            stringEntity.setContentType(contentType);
        }
        httpPost.setEntity(stringEntity);
        return sendPost4String(url, httpPost, headers, charset, timeout, checkSsl);
    }

    /**
     * POST请求,返回字符串(XML版)
     *
     * @param url url
     * @param xml xml参数
     * @return 响应字符串
     * @throws Exception
     */
    public static String doPostXML4String(String url,
                                          Map headers, String xml, int timeout, boolean checkSsl)
            throws Exception {
        return doPostString4String(url, headers, xml, DEFAULT_CHARSET, timeout, checkSsl,
                "application/xml");
    }

    /**
     * POST请求,返回字符串(JSON版)
     *
     * @param url
     * @param headers
     * @param json
     * @param timeout
     * @return String
     * @throws Exception
     */
    public static String doPostJSON4String(String url, Map headers, String json,
                                           int timeout, boolean checkSsl)
            throws Exception {
        return doPostString4String(url, headers, json, DEFAULT_CHARSET,
                timeout, checkSsl, "application/json");
    }

    /**
     * 内部方法 POST 请求,返回字符串
     *
     * @param url
     * @param httpPost
     * @param headers
     * @param charset
     * @param timeout
     * @return String
     * @throws ClientProtocolException
     * @throws IOException
     * @throws KeyManagementException
     * @throws NoSuchAlgorithmException
     * @throws KeyStoreException
     */
    private static String sendPost4String(String url, HttpPost httpPost,
                                          Map headers, String charset, int timeout, boolean checkSsl)
            throws ClientProtocolException, IOException,
            KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
        byte[] resultBytes = doPost(url, httpPost, headers, timeout, checkSsl);
        return new String(resultBytes, Charset.forName(charset));
    }

    /**
     * 内部方法 POST 请求,返回byte数组
     *
     * @param url
     * @param httpPost
     * @param headers
     * @param timeout
     * @return byte[]
     * @throws ClientProtocolException
     * @throws IOException
     * @throws KeyManagementException
     * @throws NoSuchAlgorithmException
     * @throws KeyStoreException
     */
    private static byte[] doPost(String url, HttpPost httpPost,
                                 Map headers, int timeout, boolean checkSsl)
            throws ClientProtocolException, IOException,
            KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
        CloseableHttpClient httpClient = buildHTTPClient(url, checkSsl);

        byte[] result = null;

        httpPost.setConfig(buildRequestConfig(timeout));

        for (String hkey : headers.keySet()) {
            httpPost.setHeader(hkey, headers.get(hkey));
        }

        CloseableHttpResponse response = httpClient.execute(httpPost);
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            result = EntityUtils.toByteArray(entity);
        }

        EntityUtils.consume(entity);

        return result;
    }

    public static void doPostProcess(String url, Map headers, Map params,
                                     String charset, int timeout, boolean checkSsl,
                                     IOCallback outputCallback) throws Exception {
        if (RTUtil.isEmpty(url)) {
            return;
        }
        if (params == null) {
            params = new HashMap<>();
        }
        if (RTUtil.isEmpty(charset)) {
            charset = DEFAULT_CHARSET;
        }

        CloseableHttpClient httpClient = buildHTTPClient(url, checkSsl);

        HttpPost httpPost = new HttpPost(url);
        HttpEntity reqEntity = buildMultipartEntity(params, charset);
        httpPost.setEntity(reqEntity);

        httpPost.setConfig(buildRequestConfig(timeout));

        for (String hkey : headers.keySet()) {
            httpPost.setHeader(hkey, headers.get(hkey));
        }

        CloseableHttpResponse response = httpClient.execute(httpPost);

        JSONObject info = new JSONObject();
        Header[] responseHeaders = response.getHeaders("Set-Cookie");
        for (Header responseHeader : responseHeaders) {
            HeaderElement[] headerElements = responseHeader.getElements();
            for (HeaderElement headerElement : headerElements) {
                info.put(headerElement.getName(), headerElement.getValue());
            }
        }
        outputCallback.headerInfo(info);

        HttpEntity entity = response.getEntity();

        int state = response.getStatusLine().getStatusCode();
        if (HttpStatus.SC_OK != state) {
            outputCallback.responseNot200(httpClient, response);
            EntityUtils.consume(entity);
            return;
        }

        // 获取文件长度
        final long fileLength = entity.getContentLength();
        OutputStream outputStream = outputCallback.getOutputStream();
        if (outputStream == null) {
            return;
        }
        InputStream inputStream = entity.getContent();
        int read;
        long readCount = 0;
        int index = 0;
        int buffer = outputCallback.getBufferSize();
        // 使用指定缓存
        if (buffer > 0) {
            byte[] bufferByte = new byte[buffer];
            while ((read = inputStream.read(bufferByte)) != -1) {
                outputStream.write(bufferByte, 0, read);
                readCount += read;
                outputCallback
                        .outputProcess(fileLength, read, index, readCount);
                index++;
            }
        } else {
            // 使用默认缓存
            while ((read = inputStream.read()) != -1) {
                outputStream.write(read);
                readCount += read;
                outputCallback
                        .outputProcess(fileLength, read, index, readCount);
                index++;
            }
        }
        EntityUtils.consume(entity);
    }

    /**
     * 构建HttpClient实例
     *
     * @param url
     * @return CloseableHttpClient
     * @throws KeyManagementException   KeyManagementException
     * @throws NoSuchAlgorithmException NoSuchAlgorithmException
     * @throws KeyStoreException        KeyStoreException
     */
    private static CloseableHttpClient buildHTTPClient(String url, boolean checkSsl)
            throws KeyManagementException, NoSuchAlgorithmException,
            KeyStoreException {

        boolean isSsl = url.toLowerCase().startsWith("https:");
        if (isSsl) {
            if (checkSsl) {
                SSLContext sslContext = SSLContexts
                        .custom()
                        .loadTrustMaterial((KeyStore) null,
                                TrustSelfSignedStrategy.INSTANCE).build();
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
                HttpClientBuilder clientBuilder = HttpClients.custom().setUserAgent(UA)
                        .setConnectionManager(connectionManager)
                        .setDefaultRequestConfig(buildRequestConfig(MAX_TIMEOUT));
                clientBuilder.setSSLSocketFactory(sslsf);
                return clientBuilder.build();
            } else {
                SSLContext sslContext = SSLContext.getInstance("SSLv3");
                // X509TrustManager 用于绕过验证,不用修改里面的方法
                X509TrustManager x509TrustManager = new X509TrustManager() {
                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    }

                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    }
                };
                sslContext.init(null, new TrustManager[]{x509TrustManager}, null);

                Registry registry = RegistryBuilder.create()
                        .register("http", PlainConnectionSocketFactory.INSTANCE)
                        .register("https", new SSLConnectionSocketFactory(sslContext))
                        .build();
                connectionManager = new PoolingHttpClientConnectionManager(registry);
            }

        }

        HttpClientBuilder clientBuilder = HttpClients.custom().setUserAgent(UA)
                .setConnectionManager(connectionManager)
                .setDefaultRequestConfig(buildRequestConfig(MAX_TIMEOUT));
        return clientBuilder.build();
    }

    /**
     * Map 转 NameValuePair
     *
     * @param params 请求参数
     * @return NameValuePair列表
     */
    private static List param2PairList(Map params) {
        if (params == null) {
            params = new HashMap();
        }
        List pairList = new ArrayList(
                params.size());

        for (String key : params.keySet()) {
            Object value = params.get(key);
            if (value == null) {
                continue;
            }
            pairList.add(new BasicNameValuePair(key, value.toString()));
        }

        return pairList;
    }

    /**
     * Map 转 HttpEntity
     *
     * @param params 请求参数
     * @return HttpEntity
     * @throws Exception Exception
     */
    private static HttpEntity buildMultipartEntity(Map params,
                                                   String charset) throws Exception {
        if (params == null || params.isEmpty()) {
            return null;
        }

        Charset charsetValue = Charset.forName(charset);

        MultipartEntityBuilder builder = MultipartEntityBuilder
                .create()
                .setMode(HttpMultipartMode.RFC6532)
                .setCharset(Charset.forName(charset))
                .setContentType(
                        ContentType.MULTIPART_FORM_DATA
                                .withCharset(charsetValue));

        for (String key : params.keySet()) {
            Object value = params.get(key);
            if (value == null) {
                continue;
            }
            if (value instanceof UrlFile) {
                UrlFile urlFile = (UrlFile) value;
                String fileName = urlFile.getFilename();
                if (RTUtil.isEmpty(fileName)) {
                    fileName = String.valueOf(RTUtil.getUUID());
                }
                ByteArrayBody contentBody = new ByteArrayBody(
                        urlFile.getByteFile(), fileName);
                builder.addPart(key, contentBody);
            } else if (value instanceof JSONArray) {
                JSONArray array = (JSONArray) value;
                for (int i = 0; i < array.length(); i++) {
                    Object innerValue = array.get(i);
                    if (innerValue instanceof UrlFile) {
                        UrlFile urlFile = (UrlFile) innerValue;
                        String fileName = urlFile.getFilename();
                        if (RTUtil.isEmpty(fileName)) {
                            fileName = String.valueOf(i);
                        }
                        ByteArrayBody contentBody = new ByteArrayBody(urlFile.getByteFile(), fileName);
                        builder.addPart(key, contentBody);
                    } else {
                        builder.addTextBody(key, value.toString(),
                                ContentType.TEXT_PLAIN
                                        .withCharset(charsetValue));
                    }
                }
            } else {
                builder.addTextBody(key, value.toString(),
                        ContentType.TEXT_PLAIN.withCharset(charsetValue));
            }
        }
        return builder.build();
    }

    /**
     * 创建请求参数
     *
     * @param timeout 超时时间
     * @return 请求参数
     */
    private static RequestConfig buildRequestConfig(int timeout) {
        Builder configBuilder = RequestConfig.custom();
        configBuilder.setConnectTimeout(timeout);
        configBuilder.setSocketTimeout(timeout);
        configBuilder.setConnectionRequestTimeout(timeout);
        return configBuilder.build();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy