创建不做身份鉴定的HTTPClient发送HTTPS的POST请求的工具类,解决异常:sun.security.validator.ValidatorException: PKIX path vali

https和http的区别

引用路径:HTTP和HTTPS的区别
超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加 密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信 息,比如:信用卡号、密码等支付信息。
为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS,为了数据传输的安全,HTTPS在HTTP的基 础上加入了SSL/TLS协议,SSL/TLS依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。
HTTPS协议是由SSL/TLS+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。

HTTPS和HTTP的主要区别

  1. https协议需要到CA申请证书,一般免费证书较少,因而需要一定费用。
  2. http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl/tls加密传输协议。
  3. http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
  4. http的连接很简单,是无状态的;HTTPS协议是由SSL/TLS+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

客户端在使用HTTPS方式与Web服务器通信时的步骤
第一步:客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接。
第二步:Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。
第三步:客户端的浏览器与Web服务器开始协商SSL/TLS连接的安全等级,也就是信息加密的等级。
第四步:客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。
第五步:Web服务器利用自己的私钥解密出会话密钥。
第六步:Web服务器利用会话密钥加密与客户端之间的通信。
HTTPS请求建立链接过程

由上文可知发送HTTPS请求是需要证书的,开发程序中没有证书发https请求就会抛出这样的异常sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed。而且我们服务器没有证书的,这个时候我们就需要创建不做身份鉴定的HTTPClient发送HTTPS的POST请求的工具类,去发送请求了!
工具类如下:

package com.pgl.openApi.util;

import org.apache.commons.httpclient.HttpStatus;
import org.apache.http.HeaderIterator;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
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.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
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.BasicHeader;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;

public class HttpUtils {
	private static Logger LOGGER = LoggerFactory.getLogger(HttpUtils.class);

    private static final String HTTP = "http";
    private static final String HTTPS = "https";
    private static SSLConnectionSocketFactory sslsf = null;
    private static PoolingHttpClientConnectionManager cm = null;
    private static SSLContextBuilder builder = null;

    static {
        try {
            builder = new SSLContextBuilder();

            // 全部信任 不做身份鉴定
            builder.loadTrustMaterial(null, new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                    return true;
                }
            });

            sslsf = new SSLConnectionSocketFactory(builder.build(), new String[]{"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"}, null,
                    NoopHostnameVerifier.INSTANCE);
            Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                    .register(HTTP, new PlainConnectionSocketFactory()).register(HTTPS, sslsf).build();

            cm = new PoolingHttpClientConnectionManager(registry);
            // 最大连接
            cm.setMaxTotal(2000);
            cm.setDefaultMaxPerRoute(300);//多线程调用注意配置,根据线程数设定
            IdleConnectionEvictor ice = new IdleConnectionEvictor(cm);
            ice.start();
        } catch (Exception e) {
            LOGGER.error("", e);
        }
    }


    public static CloseableHttpClient getHttpClient() throws Exception {
        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).setConnectionManager(cm)
                .setConnectionManagerShared(true).build();
        return httpClient;
    }

    public static String readHttpResponse(HttpResponse httpResponse) throws ParseException, IOException {
        StringBuilder builder = new StringBuilder();

        // 获取响应消息实体
        HttpEntity entity = httpResponse.getEntity();

        // 响应状态
        builder.append("status:" + httpResponse.getStatusLine());
        builder.append("headers:");
        HeaderIterator iterator = httpResponse.headerIterator();
        while (iterator.hasNext()) {
            builder.append("t" + iterator.next());
        }

        // 判断响应实体是否为空
        if (entity != null) {
            String responseString = EntityUtils.toString(entity);
            builder.append("response length:" + responseString.length());
            builder.append("response content:" + responseString.replace("rn", ""));
        }

        return builder.toString();
    }

    public static String sendPost(String url, String content) {
        String result = null;
        CloseableHttpClient httpClient = null;
        try {
            httpClient = getHttpClient();
            HttpPost httpPost = new HttpPost(url);

            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(0).build();
            httpPost.setConfig(requestConfig);
            httpPost.setHeader(new BasicHeader("Connection", "Keep-Alive"));
//            httpPost.setHeader("Content-Type","application/json");
            httpPost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);

            // 设置实体 优先级高
            if (content != null) {
                StringEntity entity = new StringEntity(content);// 解决中文乱码问题
//                entity.setContentEncoding("utf-8");
                entity.setContentType("application/json");
                httpPost.setEntity(entity);
            }

            long startTime = System.currentTimeMillis();
            HttpResponse httpResponse = httpClient.execute(httpPost);
            long endTime = System.currentTimeMillis();
            float seconds = (endTime - startTime) / 1000F;
            LOGGER.info("调用服务接口@" + url + "@从请求到响应共耗时:" + seconds + "秒");


            int statusCode = httpResponse.getStatusLine().getStatusCode();
            LOGGER.debug("Http请求状态:{}", statusCode);
            if (statusCode == HttpStatus.SC_OK) {
                HttpEntity resEntity = httpResponse.getEntity();
                result = EntityUtils.toString(resEntity,"UTF-8");
                LOGGER.debug("Http请求结果:{}", result);
            } else {
                readHttpResponse(httpResponse);
            }
        } catch (Exception e) {
            LOGGER.error("调用远端服务异常:n {}", e);
        }

        return result;
    }

    public static class IdleConnectionEvictor extends Thread {

        private final PoolingHttpClientConnectionManager connectionManager;

        private volatile boolean shutdown;

        public IdleConnectionEvictor(PoolingHttpClientConnectionManager connectionManager) {
            this.connectionManager = connectionManager;
        }

        @Override
        public void run() {
            try {
                while (!shutdown) {
                    synchronized (this) {
                        //3s检查一次
                        wait(3000);
                        // 关闭失效的连接
                        connectionManager.closeExpiredConnections();
                        // 选择关闭 空闲60秒的链接
                        connectionManager.closeIdleConnections(60, TimeUnit.SECONDS);
                    }
                }
            } catch (InterruptedException ex) {
                // 结束
                LOGGER.error("{}",ex);
            }
        }

        public void shutdown() {
            shutdown = true;
            synchronized (this) {
                notifyAll();
            }
        }
    }

}

相关推荐: PT一键脚本安装qBittorrent+Deluge+rTorrent+Transmission+h5ai

说明支持 Ubuntu 16.04 / 18.04、Debian 8 / 9 / 10 ;Ubuntu 14.04、Debian 7 可以选择用脚本升级系统;其他系统不支持使用 -s 参数可以跳过对系统是否受支持的检查,不过这种情况下脚本能不能正常工作就是另一…

 

© 版权声明
THE END
喜欢就支持一下吧
点赞12
分享