IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> org.apache.http.impl.client 如何请求 HTTPS 的接口? -> 正文阅读

[网络协议]org.apache.http.impl.client 如何请求 HTTPS 的接口?

背景

  • 接口类型: HTTPS
  • 工具类: org.apache.http.impl.client

发现网络上找到的许多信息并不真确,无法真正地完成 HTTPS 接口的请求,经过测试,写出如下示例代码。


要点

  • 忽略安全证书的校验
  • 设定好 TLS 版本

代码示例

以下方法,均可同时支持 HTTPHTTPS

法一

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.TrustSelfSignedStrategy;
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.ssl.SSLContextBuilder;

import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;


public class HttpsClient {

    public CloseableHttpClient getCloseableHttpsClient() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
        // SSLContextBuilder
        SSLContextBuilder builder = new SSLContextBuilder()
                .loadTrustMaterial(null, new TrustSelfSignedStrategy())
                .setSecureRandom(null)
                .useProtocol("TLSv1.3");
        // SSLContext
        SSLContext sslContext = builder.build();
        // SSLConnectionSocketFactory
        SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
                sslContext, null, null, new NoopHostnameVerifier()
        );
        // Registry
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.
                <ConnectionSocketFactory> create()
                .register("http", new PlainConnectionSocketFactory())
                .register("https", sslConnectionSocketFactory)
                .build();
        // ConnectionManager
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
        cm.setMaxTotal(2000);
        // client
        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(sslConnectionSocketFactory)
                .setConnectionManager(cm)
                .build();
        return httpClient;
    }

}

法二

import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
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.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;


@SpringBootTest
public class HttpsClientTest2 {

    /**
     * 获取SSL套接字对象 重点重点:设置tls协议的版本
     *
     * @return
     */
    public static SSLContext createIgnoreVerifySSLContext() {
        SSLContext sslContext = null;// 创建套接字对象
        try {
            sslContext = SSLContext.getInstance("TLSv1.3");//指定TLS版本
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        // 实现X509TrustManager接口,用于绕过验证
        X509TrustManager trustManager = new X509TrustManager() {
            @Override
            public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                                           String paramString) throws CertificateException {
            }
            @Override
            public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                                           String paramString) throws CertificateException {
            }
            @Override
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        try {
            sslContext.init(null, new TrustManager[] { trustManager }, null);//初始化sslContext对象
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return sslContext;
    }


    /**
     * 获取https协议请求对象
     *
     * @return
     */
    public static CloseableHttpClient getCloseableHttpsClient() {
        // 采用绕过验证的方式处理https请求
        SSLContext sslcontext = createIgnoreVerifySSLContext();
        // 设置协议http和https对应的处理socket链接工厂的对象
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
                .register("http", PlainConnectionSocketFactory.INSTANCE)
                .register("https", new SSLConnectionSocketFactory(sslcontext))
                .build();
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        // 创建自定义的httpsclient对象
        CloseableHttpClient client = HttpClients.custom()
                .setConnectionManager(connManager)
                .build();
        return client;
    }

}

测试

// 省略main class, 根据自己的情况引入即可

    public void httpsSupportTest() throws Exception {

        CloseableHttpClient httpClient = getCloseableHttpsClient();
        CloseableHttpResponse response = null;
        String result = "";

        // 测试 https
        String urlHttps = "https://my-https-url";
        String secretKeyHttps = "my-secret-key";
        // 构造 request
        HttpGet getRequest_1 = new HttpGet(urlHttps);
        getRequest_1.setHeader("secretKey", secretKeyHttps);
        // 配置 request
        RequestConfig requestConfig = RequestConfig.custom()
                // 设置连接超时时间(单位毫秒)
                .setConnectTimeout(120000)
                // 设置请求超时时间(单位毫秒)
                .setConnectionRequestTimeout(120000)
                // socket读写超时时间(单位毫秒)
                .setSocketTimeout(120000)
                // 设置是否允许重定向(默认为true)
                .setRedirectsEnabled(true).build();
        getRequest_1.setConfig(requestConfig);
        try {
            response = httpClient.execute(getRequest_1);
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                result = EntityUtils.toString(responseEntity);
                System.out.println("result: " + result);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

备注:

  • 以上方法,本质上是忽略了安全证书的校验,违背了 HTTPS 的使用初衷,不建议用到生产中。
  • 如果出现提示 TLSv1.3 is not supported 不支持的报错,请检查 JDK 的版本,因为 TLSv1.3 对 JDK 的小版本有要求(参考4)

参考

  1. https://zhuanlan.zhihu.com/p/86980940
  2. https://github.com/apache/httpcomponents-client/blob/5.1.x/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientCustomSSL.java
  3. https://stackoverflow.com/questions/19517538/ignoring-ssl-certificate-in-apache-httpclient-4-3
  4. http://openjdk.java.net/jeps/332
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-12-07 12:22:55  更:2021-12-07 12:24:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年7日历 -2024/7/8 10:01:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码