Java 使用httpclient 调用Https 接口 PKIX path building failed 问题分析。

Java 使用httpclient 调用Https 接口 PKIX path building failed 问题分析。

可能出现问题的原因
1.网站证书过期
2.网站证书没有配置齐全。
3.网站证书不是CA机构签发。
4.Java版本太老,证书库陈旧。

解决方案。
第一种:使用没有问题的证书。
第二种:将证书导入JDK下
(Lunix)具体步骤:
1. 将证书xxx.cer 复制到java安装目录 jre/lib/security 下。

2.运行如下命令    keytool -import -trustcacerts -alias 证书别名 -file 证书文件 -keystore cacerts -storepass changeit

#查看证书是否已经导入
keytool -list -alias 证书别名 -keystore cacerts -storepass changeit 
 
#根据别名删除已经导入证书
keytool -delete -alias 证书别名 –keystore cacerts -storepass changeit 

第三种:Java跳过https 检查
核心思想实现一个X509TrustManager接口,用于绕过验证
代码如下:


	publicclassHttpsUtil{
	
	/**
	*绕过验证
	*
	*@return
	*@throwsNoSuchAlgorithmException
	*@throwsKeyManagementException
	*/
	publicstaticSSLContextcreateIgnoreVerifySSL()throwsNoSuchAlgorithmException,KeyManagementException{
	SSLContextsc=SSLContext.getInstance("SSL");
	
	//实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
	X509TrustManagertrustManager=newX509TrustManager(){
	@Override
	publicvoidcheckClientTrusted(
	java.security.cert.X509Certificate[]paramArrayOfX509Certificate,
	StringparamString)throwsCertificateException{
	}
	
	@Override
	publicvoidcheckServerTrusted(
	java.security.cert.X509Certificate[]paramArrayOfX509Certificate,
	StringparamString)throwsCertificateException{
	}
	
	@Override
	publicjava.security.cert.X509Certificate[]getAcceptedIssuers(){
	returnnull;
	}
	};
	
	sc.init(null,newTrustManager[]{trustManager},null);
	returnsc;
	}
	
	/**
	*模拟请求
	*
	*@paramurl资源地址
	*@parambody参数列表
	*@paramencoding编码
	*@return
	*@throwsNoSuchAlgorithmException
	*@throwsKeyManagementException
	*@throwsIOException
	*@throwsClientProtocolException
	*/
	
	publicstaticStringdoRequest(Stringurl,JSONObjectbody,Stringencoding,Stringmethod){
	Stringresult="";
	//采用绕过验证的方式处理https请求
	try{
	SSLContextsslcontext=createIgnoreVerifySSL();
	
	//SSLContextsslcontext=SSLContext.getInstance("TLSv1.2");
	
	//设置协议http和https对应的处理socket链接工厂的对象
	Registry<ConnectionSocketFactory>socketFactoryRegistry=RegistryBuilder.<ConnectionSocketFactory>create()
	.register("http",PlainConnectionSocketFactory.INSTANCE)
	.register("https",newSSLConnectionSocketFactory(sslcontext))
	.build();
	PoolingHttpClientConnectionManagerconnManager=newPoolingHttpClientConnectionManager(socketFactoryRegistry);
	HttpClients.custom().setConnectionManager(connManager);
	
	
	//信任所有证书,关闭主机名校验
	SSLConnectionSocketFactorysslsf=newSSLConnectionSocketFactory(
	SSLContexts.custom().loadTrustMaterial(null,newTrustSelfSignedStrategy()).build(),
	NoopHostnameVerifier.INSTANCE);
	//创建Httpclient对象
	CloseableHttpClientclient=HttpClients.custom().setSSLSocketFactory(sslsf).build();
	HttpRequestBasehttpRequestBase=null;
	if(method==null||method.isEmpty()||method.equals("POST")){
	//创建post方式请求对象
	HttpPosthttpPost=newHttpPost(url);
	StringEntitys=newStringEntity(body.toJSONString(),"UTF-8");
	//发送json数据需要设置contentType
	s.setContentType("application/json");
	httpPost.setEntity(s);//设置请求参数
	装填参数
	//Listnvps=newArrayList();
	//if(map!=null){
	//for(Map.Entryentry:map.entrySet()){
	//nvps.add(newBasicNameValuePair(entry.getKey(),entry.getValue()));
	//}
	//}
	设置参数到请求对象中
	//httpPost.setEntity(newUrlEncodedFormEntity(nvps,encoding));
	
	log.info("请求地址:"+url);
	
	//设置header信息
	//httpPost.setHeader("User-Agent","Mozilla/4.0(compatible;MSIE5.0;WindowsNT;DigExt)");
	httpRequestBase=httpPost;
	}else{
	HttpGethttpGet=newHttpGet(url);
	httpRequestBase=httpGet;
	}
	//指定报文头【Content-type】、【User-Agent】
	httpRequestBase.setHeader("Content-type","application/json");
	//执行请求操作,并拿到结果(同步阻塞)
	CloseableHttpResponseresponse=client.execute(httpRequestBase);
	//获取结果实体
	HttpEntityentity=response.getEntity();
	if(entity!=null){
	//按指定编码转换结果实体为String类型
	result=EntityUtils.toString(entity,encoding);
	}
	EntityUtils.consume(entity);
	//释放链接
	response.close();
	returnresult;
	}catch(Exceptione){
	System.out.println(e);
	returnnull;
	}
	}



你可能感兴趣的:(java,https,ssl)