今天公司测试第三方接口,这个接口是用https连接的,在测试的时候报了个错:
第二中办法:
完美解决
javax.net.ssl.SSLHandshakeException:sun.security.validator。ValidatorException: PKIX路径构建失败:sun.security.provider.certpath。 SunCertPathBuilderException:无法找到请求目标的有效认证路径。
为付解决办法:
解决思路:忽略https证书验证
亲测可用
第一种:使用org.apache.http
在maven中引入:
<dependencies> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.2</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.6.2</version> </dependency> </dependencies>
然后附上代码:
import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLContextBuilder; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.util.EntityUtils; /** * HTTPS post (信任所有证书) */ public class HttpsClientUtil { private static CloseableHttpClient acceptsUntrustedCertsHttpClient() throws Exception { HttpClientBuilder b = HttpClientBuilder.create(); //内部类 SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { return true; } }).build(); b.setSslcontext( sslContext); // 不获取主机名 // 如果您不想削弱,请使用sslconnectionsocketfactory.getdefaulthostnameverfier() HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE; // 特殊部分: // -- 创建SSL套接字工厂,以使用我们削弱的“信任策略”。 // -- 创建一个注册表注册它 SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext,hostnameVerifier); Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http",PlainConnectionSocketFactory.getSocketFactory()) .register("https",sslSocketFactory) .build(); /*创建一个http客户端连接管理池 * 现在,我们使用注册表创建连接管理器。 允许多线程的使用*/ PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager(socketFactoryRegistry); b.setConnectionManager( connMgr); // 最后,创建一个httpclient类 CloseableHttpClient client = b.build(); return client; } /** * * @param url https://.... * @param jsonStr 数据 * @param charset 字符集 * @return */ public static String doPost(String url, String jsonStr, String charset){ HttpClient httpClient = null; HttpPost httpPost = null; String result = null; try{ httpClient = acceptsUntrustedCertsHttpClient(); //jdk1.6用法 //httpClient = new SSLClient(); //一般用法 httpPost = new HttpPost(url); StringEntity entity = new StringEntity(jsonStr,charset); httpPost.setEntity(entity); HttpResponse response = httpClient.execute(httpPost); if(response != null){ HttpEntity resEntity = response.getEntity(); if(resEntity != null){ result = EntityUtils.toString(resEntity,charset); } } }catch(Exception ex){ ex.printStackTrace(); } return result; } }
第二中办法:
使用java提供的jdk
import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; public class Restful { public static void main(String[] args) throws IOException, KeyManagementException, NoSuchAlgorithmException { long startTime=System.currentTimeMillis(); //获取开始时间 String result = null; HttpsURLConnection.setDefaultHostnameVerifier(new Restful().new NullHostNameVerifier()); SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); URL url = new URL("https://....."); /*??????请求的路径????*/ // 打开restful链接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST");// POST GET PUT DELETE // 设置访问提交模式,表单提交 conn.setRequestProperty("Content-Type", "application/json;charset=utf-8"); conn.setConnectTimeout(130000);// 连接超时 单位毫秒 conn.setReadTimeout(130000);// 读取超时 单位毫秒 //加入数据 conn.setRequestMethod("POST"); //设置请求方式 conn.setDoOutput(true);//URL 连接可用于输入和/或输出。如果打算使用 URL 连接进行输出,则将 DoOutput 标志设置为 true;如果不打算使用,则设置为 false。默认值为 false。 DataOutputStream out = new DataOutputStream( conn.getOutputStream()); String content=null;/*?????请求的参数?????*/ out.writeBytes(content);//将指定的字节写入此输出流。 out.flush(); out.close(); //获取输入流 BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8")); int code = conn.getResponseCode(); if (HttpsURLConnection.HTTP_OK == code){ String temp = in.readLine(); /*连接成一个字符串*/ while (temp != null) { if (result != null) result += temp; else result = temp; temp = in.readLine(); } } long endTime=System.currentTimeMillis(); //获取结束时间 System.out.println("返回:"+result); System.out.println("程序运行时间: "+(endTime-startTime)+"毫秒"); //程序运行时间: 1008毫秒=1.008秒 1382毫秒=1.382秒 // 读取请求返回值 /*byte bytes[] = new byte[1024]; InputStream inStream = conn.getInputStream(); inStream.read(bytes, 0, inStream.available()); System.out.println(new String(bytes, "utf-8"));*/ } static TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { // TODO Auto-generated method stub } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { // TODO Auto-generated method stub } public X509Certificate[] getAcceptedIssuers() { // TODO Auto-generated method stub return null; } } }; public class NullHostNameVerifier implements HostnameVerifier { /* * (non-Javadoc) * * @see javax.net.ssl.HostnameVerifier#verify(java.lang.String, * javax.net.ssl.SSLSession) */ public boolean verify(String arg0, SSLSession arg1) { // TODO Auto-generated method stub return true; } } }
完美解决