遇到了“unable to find valid certification path to requested target”这样的问题。
错误详情如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1391)         at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)         at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)         at java.util.concurrent.FutureTask.run(FutureTask.java:266)         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)         at java.lang.Thread.run(Thread.java:745) Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target         at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)         at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)         at sun.security.validator.Validator.validate(Validator.java:260)         at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)         at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)         at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)         at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1460)         ... 35 common frames omitted Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target         at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:145)         at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:131)         at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)         at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)         ... 41 common frames omitted | 
从异常信息中可以看到错误是因为找不到证书导致的。
解决方案有两个。
正常的方案当然是找到证书并安装证书。这种方案能找到一大把,在这里不做展开。
说个暴力的方案:取消证书认证,信任所有请求链接。
使用的工具是fluent-http-client,maven地址是:
| 1 2 3 4 5 |         <dependency>             <groupId>org.apache.httpcomponents</groupId>             <artifactId>fluent-hc</artifactId>             <version>4.5.4</version>         </dependency> | 
首先创建一个自定义的HttpClient实例。这个实例将信任所有的请求链接。实例详情如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |     final static PoolingHttpClientConnectionManager CONN_MGR;     final static org.apache.http.client.HttpClient CLIENT;     static {         SSLConnectionSocketFactory sf = null;         try {             //信任所有             SSLContext sslc = new SSLContextBuilder().loadTrustMaterial(null, (chain, authType) -> true).build();             sf = new SSLConnectionSocketFactory(sslc);         } catch (Exception e) {             logger.error("Create socket factory failed.", e);         }         final Registry<ConnectionSocketFactory> sfr = RegistryBuilder.<ConnectionSocketFactory>create()                 .register("http", PlainConnectionSocketFactory.getSocketFactory())                 .register("https", null != sf ? sf : SSLConnectionSocketFactory.getSocketFactory())                 .build();         CONN_MGR = new PoolingHttpClientConnectionManager(sfr);         CONN_MGR.setDefaultMaxPerRoute(1024);         CONN_MGR.setMaxTotal(512);         CONN_MGR.setValidateAfterInactivity(1000);         CLIENT = HttpClientBuilder.create()                 // 这里主要用来避免使用http链接请求实际为https的地址                 .setSSLSocketFactory(sf)                 .setConnectionManager(CONN_MGR)                 .build();     } | 
注意代码中的两处注释,是关键。
然后绑定新创建的实例,执行一个Get请求:
| 1 | Executor.newInstance(CLIENT).execute(Request.Get("http://www.json.cn?a=b")).returnResponse(); | 
就这样。
#######
发表评论