创建信任所有证书的HttpClient:Java 实现 HTTPS 接口调用,等效于curl -k

news2025/5/23 10:02:03

在 Java 生态中,HttpClientFeign 都是调用第三方接口的常用工具,但它们的定位、设计理念和使用场景有显著差异。以下是详细对比:


DIFF1. 定位与抽象层级

特性HttpClientFeign
层级底层 HTTP 客户端库(处理原始请求/响应)声明式 HTTP 客户端(基于接口和注解)
核心目标提供灵活的 HTTP 通信能力简化 REST 客户端开发,隐藏 HTTP 细节
依赖关系独立使用(如 Apache HttpClient/OkHttp)需依赖 HttpClient(默认集成 Ribbon/OkHttp)

DIFF.性能与资源**

维度HttpClientFeign
启动开销低(直接使用)较高(需生成动态代理类)
运行时性能更优(无额外抽象层)轻微损耗(反射/动态代理)
连接池需手动配置 PoolingHttpClientConnectionManager自动复用底层 HttpClient 连接池
本文仅对HttpClient调用https接口调用做一个总结,先上代码:
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustAllStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.nio.charset.StandardCharsets;

/**
 * HTTPS 接口调用工具类
 * 包含 GET 和 POST 请求方法,支持自定义请求头和跳过证书验证(仅限测试环境)
 */
public class HttpsClientUtil {

    /**
     * 发送 HTTPS GET 请求
     * @param url 请求地址
     * @param headers 请求头数组,格式为 {"key1:value1", "key2:value2"}
     * @return 响应内容
     * @throws Exception 如果请求过程中发生错误
     */
    public static String doGet(String url, String[] headers) throws Exception {
        // 1. 创建支持 HTTPS 的 HttpClient 实例
        try (CloseableHttpClient httpClient = createHttpsClient()) {
            // 2. 创建 GET 请求对象
            HttpGet httpGet = new HttpGet(url);
            
            // 3. 设置请求头(如果有)
            if (headers != null) {
                for (String header : headers) {
                    String[] kv = header.split(":");
                    if (kv.length == 2) {
                        httpGet.addHeader(kv[0].trim(), kv[1].trim());
                    }
                }
            }
            
            // 4. 执行请求并获取响应
            HttpResponse response = httpClient.execute(httpGet);
            
            // 5. 解析响应内容
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                return EntityUtils.toString(entity, StandardCharsets.UTF_8);
            }
            return null;
        }
    }

    /**
     * 发送 HTTPS POST 请求(JSON格式)
     * @param url 请求地址
     * @param jsonBody JSON格式的请求体
     * @param headers 请求头数组
     * @return 响应内容
     * @throws Exception 如果请求过程中发生错误
     */
    public static String doPost(String url, String jsonBody, String[] headers) throws Exception {
        try (CloseableHttpClient httpClient = createHttpsClient()) {
            // 1. 创建 POST 请求对象
            HttpPost httpPost = new HttpPost(url);
            
            // 2. 设置请求头和请求体
            httpPost.addHeader("Content-Type", "application/json");
            if (headers != null) {
                for (String header : headers) {
                    String[] kv = header.split(":");
                    if (kv.length == 2) {
                        httpPost.addHeader(kv[0].trim(), kv[1].trim());
                    }
                }
            }
            
            // 3. 设置 JSON 请求体
            if (jsonBody != null) {
                httpPost.setEntity(new StringEntity(jsonBody, StandardCharsets.UTF_8));
            }
            
            // 4. 执行请求并获取响应
            HttpResponse response = httpClient.execute(httpPost);
            
            // 5. 解析响应内容
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                return EntityUtils.toString(entity, StandardCharsets.UTF_8);
            }
            return null;
        }
    }

    /**
     * 创建支持 HTTPS 的 HttpClient 实例
     * 注意:此方法跳过证书验证,仅适用于测试环境!
     * 生产环境应使用正确的证书验证方式
     */
    private static CloseableHttpClient createHttpsClient() throws Exception {
        // 1. 创建 SSLContext,配置信任所有证书(不安全,仅测试用)
        SSLContext sslContext = SSLContextBuilder.create()
                .loadTrustMaterial(new TrustAllStrategy()) // 信任所有证书
                .build();
        
        // 2. 创建 SSL 连接工厂,跳过主机名验证
        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
                sslContext,
                NoopHostnameVerifier.INSTANCE); // 跳过主机名验证
        
        // 3. 配置请求超时参数
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(5000) // 连接超时 5秒
                .setSocketTimeout(10000) // 请求超时 10秒
                .setConnectionRequestTimeout(2000) // 从连接池获取连接超时 2秒
                .build();
        
        // 4. 创建 HttpClient 实例
        return HttpClients.custom()
                .setSSLSocketFactory(sslSocketFactory) // 设置 SSL 工厂
                .setDefaultRequestConfig(requestConfig) // 设置超时配置
                .build();
    }

    /**
     * 测试方法
     */
    public static void main(String[] args) {
        try {
            // 测试 GET 请求
            String getUrl = "https://jsonplaceholder.typicode.com/posts/1";
            String getResponse = doGet(getUrl, null);
            System.out.println("GET 响应:\n" + getResponse);
            
            // 测试 POST 请求
            String postUrl = "https://jsonplaceholder.typicode.com/posts";
            String jsonBody = "{\"title\":\"foo\",\"body\":\"bar\",\"userId\":1}";
            String[] headers = {"Authorization: Bearer token123"};
            String postResponse = doPost(postUrl, jsonBody, headers);
            System.out.println("\nPOST 响应:\n" + postResponse);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

关键代码解析

1. 创建信任所有证书的 SSLContext

SSLContext sslContext = SSLContextBuilder.create()
        .loadTrustMaterial(new TrustAllStrategy()) // 信任所有证书
        .build();
  • TrustAllStrategy 是 Apache HttpClient 提供的策略,会信任所有证书(包括自签名和过期证书)
  • 生产环境警告:这种配置不安全,只应在测试环境使用

2. 配置 SSL 连接工厂

SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
        sslContext,
        NoopHostnameVerifier.INSTANCE); // 跳过主机名验证
  • NoopHostnameVerifier 会跳过主机名验证
  • 实际项目中应该使用 DefaultHostnameVerifier

3. 设置请求超时

RequestConfig requestConfig = RequestConfig.custom()
        .setConnectTimeout(5000) // 连接超时 5秒
        .setSocketTimeout(10000) // 请求超时 10秒
        .setConnectionRequestTimeout(2000) // 从连接池获取连接超时 2秒
        .build();
  • 防止因网络问题导致线程长时间阻塞

4. 创建 HttpClient 实例

return HttpClients.custom()
        .setSSLSocketFactory(sslSocketFactory) // 设置 SSL 工厂
        .setDefaultRequestConfig(requestConfig) // 设置超时配置
        .build();
  • 使用 try-with-resources 确保资源自动关闭

生产环境建议

  1. 不要跳过证书验证
    应配置正确的信任库:

    SSLContext sslContext = SSLContextBuilder.create()
            .loadTrustMaterial(new File("/path/to/truststore.jks"), "password".toCharArray())
            .build();
    
  2. 使用连接池
    对于高频请求,应配置连接池:

    PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
    connManager.setMaxTotal(100);
    connManager.setDefaultMaxPerRoute(20);
    
  3. 添加重试机制
    对临时性网络错误实现自动重试

  4. 使用更现代的 HTTP 客户端
    考虑使用 OkHttp 或 Java 11+ 的 HttpClient

这个实现提供了完整的 HTTPS 调用功能,可以直接用于项目开发(测试环境)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2383807.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入理解 PlaNet(Deep Planning Network):基于python从零实现

引言:基于模型的强化学习与潜在动态 基于模型的强化学习(Model-based Reinforcement Learning)旨在通过学习环境动态的模型来提高样本效率。这个模型可以用来进行规划,让智能体在不需要与真实环境进行每一次决策交互的情况下&…

仿腾讯会议——视频发送接收

1、 添加音频模块 2、刷新图片,触发重绘 3、 等比例缩放视频帧 4、 新建视频对象 5、在中介者内定义发送视频帧的函数 6、完成发送视频的函数 7、 完成开启/关闭视频 8、绑定视频的信号槽函数 9、 完成开启/关闭视频 10、 完成发送视频 11、 完成刷新图片显示 12、完…

从3.7V/5V到7.4V,FP6291在应急供电智能门锁中的应用

在智能家居蓬勃发展的当下,智能门锁以其便捷、安全的特性,成为现代家庭安防的重要组成部分。在智能门锁电量耗尽的情况下,应急电源外接移动电源(USB5V输入) FP6291升压到7.4V供电可应急开锁。增强用户在锁具的安全性、…

【人工智障生成日记1】从零开始训练本地小语言模型

🎯 从零开始训练本地小语言模型:MiniGPT TinyStories(4090Ti) 🧭 项目背景 本项目旨在以学习为目的,从头构建一个完整的本地语言模型训练管线。目标是: ✅ 不依赖外部云计算✅ 完全本地运行…

Selenium-Java版(frame切换/窗口切换)

frame切换/窗口切换 前言 切换到frame 原因 解决 切换回原来的主html 切换到新的窗口 问题 解决 回到原窗口 法一 法二 示例 前言 参考教程:Python Selenium Web自动化 2024版 - 自动化测试 爬虫_哔哩哔哩_bilibili 上期文章:Sel…

一文深度解析:Pump 与 PumpSwap 的协议机制与技术差异

在 Solana 链上,Pump.fun 和其延伸产品 PumpSwap 构成了 meme coin 发行与流通的两大核心场景。从初期的游戏化发行模型,到后续的自动迁移与交易市场,Pump 系列协议正在推动 meme coin 从“爆发性投机”走向“协议化运营”。本文将从底层逻辑…

星云智控v1.0.0产品发布会圆满举行:以创新技术重构物联网监控新生态

星云智控v1.0.0产品发布会圆满举行:以创新技术重构物联网监控新生态 2024年5月15日,成都双流蛟龙社区党群服务中心迎来了一场备受业界瞩目的发布会——优雅草科技旗下”星云智控v1.0.0”物联网AI智控系统正式发布。本次发布会吸引了包括沃尔沃集团、新希…

SpringBoot(一)--- Maven基础

目录 前言 一、初始Maven 1.依赖管理 2.项目构建 3.统一项目结构 二、IDEA集成Maven 1.Maven安装 2.创建Maven项目 2.1全局设置 2.2 创建SpringBoot项目 2.3 常见问题 三、单元测试 1.JUnit入门 2.断言 前言 Maven 是一款用于管理和构建Java项目的工具&#xff…

基于FPGA控制电容阵列与最小反射算法的差分探头优化设计

在现代高速数字系统测试中,差分探头的信号完整性直接影响测量精度。传统探头存在阻抗失配导致的信号反射问题,本文提出一种通过FPGA动态控制电容阵列,结合最小反射算法的优化方案,可实时调整探头等效容抗,将信号反射损…

kakfa 基本了解

部署结构 Kafka 使用zookeeper来协商和同步,但是kafka 从版本3.5正式开始deprecate zookeeper, 同时推荐使用自带的 kraft. 而从4.0 开始则不再支持 zookeeper。 所以 kafka 是有control plane 和 data plane 的。 data plane 就是broker,control plane…

Origin绘制多因子柱状点线图

多因子柱状点线图是一种结合柱状图和点线图的复合图表,常用于同时展示多个因子(变量)在不同分组下的分布和趋势变化。 适用场景: (1)比较多个因子在不同分组中的数值大小(柱状图)&a…

Web漏洞扫描服务的特点与优势:守护数字时代的安全防线

在数字化浪潮中,Web应用程序的安全性已成为企业业务连续性和用户信任的核心要素。随着网络攻击手段的不断升级,Web漏洞扫描服务作为一种主动防御工具,逐渐成为企业安全体系的标配。本文将从特点与优势两方面,解析其价值与应用场景…

抛弃传统P2P技术,EasyRTC音视频基于WebRTC打造教育/会议/远程巡检等场景实时通信解决方案

一、方案背景 随着网络通信发展,实时音视频需求激增。传统服务器中转方式延迟高、资源消耗大,WebP2P技术由此兴起。EasyRTC作为高性能实时通信平台,集成WebP2P技术,实现低延迟、高效率音视频通信,广泛应用于教育、医疗…

俄罗斯军总参情报局APT28组织瞄准援乌后勤供应链发起全球网络攻击

2025年5月,由美国、英国、欧盟和北约网络安全与情报机构联合发布的最新网络安全公告披露,俄罗斯军总参情报局(GRU)第85特别服务中心第26165部队(又称APT28、Fancy Bear、Forest Blizzard和BlueDelta)正持续…

杰发科技AC7801——PWM获取固定脉冲个数

测试通道6 在初始化时候打开通道中断 void PWM1_GenerateFrequency(void) {PWM_CombineChConfig combineChConfig[1]; //组合模式相关结构体PWM_IndependentChConfig independentChConfig[2];//独立模式相关结构体PWM_ModulationConfigType pwmConfig; //PWM模式相关结构体PWM…

MacBookPro上macOS安装第三方应用报错解决方案:遇到:“无法打开“XXX”,因为无法确定(验证)开发者身份?怎么解决

MacBook Pro 上 macOS 安装第三方应用报错解决方案 —— 彻底搞定「无法打开“XXX”,因为无法确定开发者身份」 适用系统:macOS Catalina 10.15 ~ macOS Sonoma 14.x 适用机型:Intel / Apple Silicon 全系 MacBook Pro 文章目录 **MacBook P…

RAG(Retrieval-Augmented-Generation)检索增强生成

什么是RAG(检索增强生成)? RAG是一种AI框架,结合传统的数据检索技术和LLM(大语言模型)的优势,通过将外部数据和LLM生成语言技能集合,对LLM的输出进行优化,使输出更准确、…

黑马点评前端Nginx启动失败问题解决记录

Nginx启动失败问题解决记录 问题描述 在学习黑马Redis课程时,启动黑马点评Nginx前端项目发现: 无法访问8080端口检查Windows端口占用情况(无占用)结论:Nginx服务未成功启动 错误日志分析 在nginx安装目录下的logs…

第12天-Python+Qt5开发实战:10大经典案例与深度解析

1. 基础窗口与信号槽机制 python 复制 下载 import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButtonclass MainWindow(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("信号槽示例")btn = QPushButton("…

人工智能培训:解锁未来职场竞争力的核心路径与课程内容解析

当AI绘画工具在几秒内生成一幅媲美专业画师的作品,当AI程序员自主优化代码逻辑,当AI客服精准解答复杂问题——一个现实愈发清晰:人工智能正在重新定义“专业能力”的边界。 对于普通人而言,这场变革既带来焦虑,也孕育机…