Http工具类HttpUtil

参考: 关于JAVA发送Https请求(HttpsURLConnection和HttpURLConnection) https://www.cnblogs.com/mengen/p/9138214.html
1、支持https:忽略证书验证过程
2、支持设置http请求参数、编码等
3、

  package com.util.http;


import javax.net.ssl.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.Map.Entry;


/**
 * http、https 请求工具类
 */
public class HttpUtil {

    private static final String CHARSET_UTF8 = "UTF-8";

    private static final String METHOD_GET = "GET"; // GET
    private static final String METHOD_POST = "POST";// POST
    private static final int DEF_CONN_TIMEOUT = 5 * 1000;
    private static final int DEF_READ_TIMEOUT = 60 * 1000;

    public static final String CONTENT_TYPE_XFORM = "application/x-www-form-urlencoded";
    public static final String CONTENT_TYPE_JSON = "application/json";
    //最大接收报文长度4M
    private static final int PACKAGE_MAXLEN = 4 * 1024 * 1024;

    /**
     * 初始化http请求参数,建立连接
     *
     * @param url
     * @param method
     * @param headers 请求头
     * @return
     * @throws Exception
     */
    private static HttpURLConnection buildHttpConn(String url, String method, String contentType, Map<String, String> headers) throws Exception {
        URL _url = new URL(url);
        HttpURLConnection httpConn;
        if (!isHttps(url)) {
            httpConn = (HttpURLConnection) _url.openConnection();
        } else {
            httpConn = (HttpsURLConnection) _url.openConnection();
            //JDK1.7默认支持TLSV1版本协议,JDK1.8默认支持TLSV1.2 解决协议版本兼容问题(TlsCompatSocketFactory)
            //System.setProperty("https.protocols", "TLSv1");
            SSLContext sslContext = SSLContext.getInstance("TLS");
            //忽略证书验证过程
            TrustManager[] tm = {new MyX509TrustManager()};
            sslContext.init(null, tm, new java.security.SecureRandom());
            SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            ((HttpsURLConnection) httpConn).setSSLSocketFactory(new TlsCompatSocketFactory(sslContext.getSocketFactory()));
            // 设置域名校验
            ((HttpsURLConnection) httpConn).setHostnameVerifier(new TrustAnyHostnameVerifier());
        }
        // 连接超时
        httpConn.setConnectTimeout(DEF_CONN_TIMEOUT);
        // 读取超时
        httpConn.setReadTimeout(DEF_READ_TIMEOUT);
        //禁用缓存
        httpConn.setUseCaches(false);
        httpConn.setRequestMethod(method);
        if (isEmptyString(contentType)) {
            //默认表单内容
            contentType = "application/x-www-form-urlencoded";
        }
        httpConn.setRequestProperty("Content-Type", contentType);
        //httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        //http.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36");
        if (null != headers && !headers.isEmpty()) {
            for (Entry<String, String> entry : headers.entrySet()) {
                httpConn.setRequestProperty(entry.getKey(), entry.getValue());
            }
        }
        httpConn.setDoOutput(true);
        httpConn.setDoInput(true);
        httpConn.connect();
        return httpConn;
    }


    /**
     * @param url
     * @param method
     * @param contentType
     * @param headers
     * @param reqData
     * @param sendEncoding 发送数据编码
     * @param rcvEncoding  接收数据编码
     * @return
     * @throws Exception
     */
    public static String sendRequest(String url, String method, String contentType, Map<String, String> headers, String reqData, String sendEncoding, String rcvEncoding) throws Exception {
        HttpURLConnection httpConn = null;
        String responseStr = "";
        if (isEmptyString(sendEncoding)) {
            sendEncoding = CHARSET_UTF8;
        }
        if (isEmptyString(rcvEncoding)) {
            rcvEncoding = CHARSET_UTF8;
        }
        try {
            try {
                httpConn = buildHttpConn(url, method, contentType, headers);
            } catch (SSLHandshakeException e) {

            }


            if (METHOD_POST.equals(method) && !isEmptyString(reqData)) {
                try (OutputStream out = httpConn.getOutputStream()) {
                    out.write(reqData.getBytes(sendEncoding));
                    out.flush();
                }
            }
            //返回结果码处理
            int rescode = httpConn.getResponseCode();
            String resmsg = httpConn.getResponseMessage();
            System.out.println("Server response: " + rescode + " " + resmsg);
            if (rescode != 200) {
                throw new Exception("Server response: " + rescode + " " + resmsg);
            }
            //读取服务器返回数据
            try (BufferedInputStream bis = new BufferedInputStream(httpConn.getInputStream())) {
                StringBuffer sb = new StringBuffer();
                byte[] bfBytes = new byte[10240];
                int len;
                int sumlen = 0;
                while ((len = bis.read(bfBytes)) != -1) {
                    //sb.append(new String(bfBytes, 0, len, rcvEncoding));
                    sb.append(new String(bfBytes, 0, len));
                    sumlen += len;
                    if (sumlen > PACKAGE_MAXLEN) {
                        throw new Exception("通讯接收报文超长");
                    }
                }
                //String默认编码ISO8859-1(单字节编码),编码转换为rcvEncoding
                responseStr = new String(sb.toString().getBytes(), rcvEncoding);
            }
        } catch (Exception e) {
            //TODO
            e.printStackTrace();
            throw e;
        } finally {
            if (httpConn != null) {
                httpConn.disconnect();// 关闭连接
            }
        }
        return responseStr;
    }


    public static String get(String url) throws Exception {
        return get(url, null);
    }

    public static String get(String url, Map<String, String> params) throws Exception {
        return get(url, null, params, null);
    }

    public static String get(String url, Map<String, String> headers, Map<String, String> params, String rcvEncoding) throws Exception {
        return sendRequest(initParams(url, params), METHOD_GET, null, headers, null, null, rcvEncoding);
    }

    public static String post(String url, String contentType, String reqData) throws Exception {
        return post(url, contentType, null, reqData, null, null);
    }

    public static String post(String url, String contentType, Map<String, String> headers, String reqData, String sendEncoding, String rcvEncoding) throws Exception {
        return sendRequest(url, METHOD_POST, contentType, headers, reqData, sendEncoding, rcvEncoding);
    }

    /**
     * 功能描述: 构造请求参数
     *
     * @return 返回类型:
     * @throws Exception
     */
    public static String initParams(String url, Map<String, String> params) throws Exception {
        if (null == params || params.isEmpty()) {
            return url;
        }
        StringBuilder sb = new StringBuilder(url);
        if (url.indexOf("?") == -1) {
            sb.append("?");
        }
        sb.append(map2Url(params));
        return sb.toString();
    }

    /**
     * map构造url
     *
     * @return 返回类型:
     * @throws Exception
     */
    public static String map2Url(Map<String, String> paramToMap) throws Exception {
        if (null == paramToMap || paramToMap.isEmpty()) {
            return null;
        }
        StringBuffer url = new StringBuffer();
        boolean isfist = true;
        for (Entry<String, String> entry : paramToMap.entrySet()) {
            if (isfist) {
                isfist = false;
            } else {
                url.append("&");
            }
            url.append(entry.getKey()).append("=");
            String value = entry.getValue();
            if (!isEmptyString(value)) {
                url.append(URLEncoder.encode(value, CHARSET_UTF8));
            }
        }
        return url.toString();
    }

    private static boolean isEmptyString(String s) {
        return s == null || s.length() == 0;
    }

    /**
     * 检测是否https
     *
     * @param url
     */
    private static boolean isHttps(String url) {
        return url.startsWith("https");
    }

    /**
     * 信任任何证书
     */
    private static class MyX509TrustManager implements X509TrustManager {
        //检查客户端证书
        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

        }

        //检查服务器端证书
        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            //返回受信任的X509证书数组
            return new X509Certificate[0];
        }
    }

    /**
     * https 域名校验
     *
     * @return
     */
    private static class TrustAnyHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }
}


package com.util.http;

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * Created by wzh-zhua on 2020/3/29.
 */
public class TlsCompatSocketFactory extends SSLSocketFactory {
    private static final String[] TLS_VERSION_LIST = {"TLSv1", "TLSv1.1", "TLSv1.2"};

    private final SSLSocketFactory target;

    public TlsCompatSocketFactory(SSLSocketFactory target) {
        this.target = target;
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return target.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return target.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        return supportTLS(target.createSocket(s, host, port, autoClose));
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
        return supportTLS(target.createSocket(host, port));
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
        return supportTLS(target.createSocket(host, port, localHost, localPort));
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        return supportTLS(target.createSocket(host, port));
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        return supportTLS(target.createSocket(address, port, localAddress, localPort));
    }

    private Socket supportTLS(Socket s) {
        if (s instanceof SSLSocket) {
            ((SSLSocket) s).setEnabledProtocols(TLS_VERSION_LIST);
        }
        return s;
    }
}

你可能感兴趣的:(计算机网络,HTTP)