httpClient 处理https请求

本文解决HTTP客户端请求HTTPS链接时遇到域名不匹配的SSLException异常问题,通过自定义SSLContext、X509TrustManager和SSLConnectionSocketFactory实现忽略证书验证,确保请求正常进行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天遇到了个问题,相信很多人都遇到过,使用Httpclient请求https的链接是抛出类似的如下异常

javax.net.ssl.SSLException: hostname in certificate didn't match:www.XXX.com != www.xxx.com

首先来说这个问题产生的原因,根据百度的资料,和实际的情况,我的分析结果是

所请求的网站域名和服务器上的证书中的域名不符,导致请求方域名不匹配的异常

 

解决这个问题,还要看实际情况,请求的目的是什么,如果是要保证证书的正确,那就不用往下看了,因为下面说的是不需要保证证书正确的情况,想要保证证书正确,只能求助其他的大神,需要导入证书之类的,貌似很高端

 

我还是直接说下不需要保证证书正确,只要保证正常请求就可以的情况;

首先来说,需要有如下几个关键点

1,SSLContext sslContext

2,X509TrustManager tm

3,SSLConnectionSocketFactory sslsf

这三个我也没有深入研究,第一个我猜是构建那种协议,是SSL还是TLS之类的,第二个完全没想法

第三个就是httpClient链接的时候使用的socekt的工厂了。需要使用到前两个变量作为参数。

 

来看每个变量的初始化

sslContext= SSLContext.getInstance("SSL");//sslContext= SSLContext.getInstance("TLS");

这里是SSL还是TLS,要看自己的应用情况,我的情况,两种都合适,没所谓,我印象中TLS类似于继承自SSL,不知道区别是哪里,知道的朋友还请赐教

 

在看tm

X509TrustManager tm = new X509TrustManager() {

                public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {

                }

                public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
                }

                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };

 这个就是new了一个,没做什么操作

接下来需要对sslContext初始化

sslContext.init(null, new TrustManager[] { tm }, null);

这里就是tm的用武之地了,用于初始化sslContext

接下来就是SSLConnectionSocketFactory sslsf

的初始化

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

这里很关键的是第二个参数,个人理解,信任任何证书,说白了也就是不管证书,怎么样都信任,去访问

 

然后两种方式使我们设置的生效

一种是

Registry<ConnectionSocketFactory> reg = RegistryBuilder.<ConnectionSocketFactory> create()

 

                    .register("http", PlainConnectionSocketFactory.INSTANCE).register("https", sslsf).build();

使用registry,注意别把build丢了,这个很关键

 

另一种方式是直接在构建httpClient的时候设置

HttpClients.custom().setSSLSocketFactory(sslsf).build();

这里的HttpClients.custom()拿到的就是HttpClientBuilder

如果你有这个中间变量,可以直接使用

 

这样就可以解决问题

 

顺便说一句,我也尝试过使用类似

httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme(null, null, null));

注意Scheme这里参数需要填的,并非为空,此处仅是举例

这种方式并未成功,而且这种方式使过期的方式

未成功的原因可能是我使用的是CloseableHttpClient,如果使用defaultHttpClient就可以成功,具体原因还有待研究

 

各位共勉!

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值