问题描述
我正在尝试使用HttpClient从我的代码访问网站:
I am trying to access a website from my code using HttpClient :
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("https://www.datamed.org/search.php?query=gene&searchtype=data");
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpclient.execute(httpget, responseHandler);
这是我得到的错误:
Exception in thread "main" javax.net.ssl.SSLException: hostname in certificate didn't match: <www.datamed.org> != <ucrexdc.ucsd.edu> OR <ucrexdc.ucsd.edu>
我从浏览器检查了证书,它看起来正确,并且名称正确.不确定从哪里获取 ucrexdc.ucsd.edu
.
I checked the certificate from browser, it seems correct, with correct names.Not sure from where it is picking up ucrexdc.ucsd.edu
.
如果我使用代理,代码确实有效.在StackOverflow上解决了许多类似的问题,但是在大多数情况下,服务器在用户的控制之下.就我而言,这是一个已经存在的网站.而且我只在这个网站上有这个问题.
The code does work if I use a proxy.Gone through a lot of similar issues on StackOverflow, but in most cases the server was under user's control. In my case, this is an already existing website. and i have this problem only for this website.
我的环境有问题吗?
更新:
我发现两个网站( datamed.org
和 ucrexdc.ucsd.edu
)具有相同的IP, 169.228.51.21
.可能有问题吗,为什么浏览器没有这个问题?
I found out that both the websites (datamed.org
and ucrexdc.ucsd.edu
) have the same IP , 169.228.51.21
. Can it be a problem, why doesn't the browser have issues with this?
更新2:
我正在使用apache http-client 4.3.1
,
当我更新到 4.4.1
时,它已解决.该问题很可能与SNI有关.
I was using apache http-client 4.3.1
,
When i updated to 4.4.1
, it was resolved. the issue was most possibly related to SNI.
推荐答案
HttpClient提供了两种实现主机名验证的实现.
HttpClient provides two implementations for Hostname verification.
- DefaultHostnameVerifier
- NoopHostnameVerifier
默认情况下,HttpClient使用 DefaultHostnameVerifier 实现.您可以尝试其他主机名验证程序实现.
by default HttpClient uses DefaultHostnameVerifier implementation. You can try the different hostname verifier implementation.
SSLContext sslContext = SSLContexts.createSystemDefault();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
HttpClient httpClient = HttpClientBuilder.create().setSSLSocketFactory(sslsf).build();
这篇关于HttpClient:主机名不匹配-可从浏览器访问,但不能从代码访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!