若是咱們直接經過普通的方式對https的連接發送請求,會報一個以下的錯誤:html
javax.net.ssl.SSLHandshakeException: 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.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1886) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) at sun.security.ssl.Handshaker.process_record(Handshaker.java:804) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:702) at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) at java.io.FilterOutputStream.flush(FilterOutputStream.java:140) at org.apache.commons.httpclient.methods.StringRequestEntity.writeRequest(StringRequestEntity.java:146) at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499) at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114) at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096) at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398) at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323) at com.xxx.yyy.portal.utils.HttpRequest.exeRequest(HttpRequest.java:148) at com.xxx.yyy.portal.utils.HttpDemo1.main(HttpDemo1.java:15) 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:385) 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:326) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1323) ... 20 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380) ... 26 more
這個錯表示https的連接須要證書驗證,普通的方式不能完成https連接的請求。java
直接給出代碼,封裝成工具類,提供了兩種實現方式。apache
第一種完成使用Java自身的Api實現;json
第二種使用Apache的httpclient相關jar包實現,注意須要引入apache httpclient的相關依賴包,以下:session
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.2.1</version> </dependency>
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.3.6</version> </dependency>
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.3.1</version> </dependency>
工具類app
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.URL; import java.net.URLConnection; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; 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; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; 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.SSLConnectionSocketFactory; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.util.EntityUtils; public class HttpRequest { public static String exeHttpsRequest(String URL, String message, String token) { String body = ""; CloseableHttpClient client = null; try { // 採用繞過驗證的方式處理https請求 SSLContext sslcontext = createIgnoreVerifySSL(); // 設置協議http和https對應的處理socket連接工廠的對象 Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create() .register("http", PlainConnectionSocketFactory.INSTANCE) .register("https", new SSLConnectionSocketFactory(sslcontext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)) .build(); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager( socketFactoryRegistry); HttpClients.custom().setConnectionManager(connManager); // 建立自定義的httpclient對象 client = HttpClients.custom().setConnectionManager(connManager).build(); // CloseableHttpClient client = HttpClients.createDefault(); // 建立post方式請求對象 HttpPost httpPost = new HttpPost(URL); // 指定報文頭Content-type、User-Agent httpPost.setHeader("Content-type", "application/json"); httpPost.setHeader("Authorization", "Bearer " + token); httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2"); StringEntity stringEntity = new StringEntity(message, "UTF-8"); stringEntity.setContentType("application/json"); httpPost.setEntity(stringEntity); // 執行請求操做,並拿到結果(同步阻塞) CloseableHttpResponse response = client.execute(httpPost); // 獲取結果實體 HttpEntity entity = response.getEntity(); if (entity != null) { // 按指定編碼轉換結果實體爲String類型 body = EntityUtils.toString(entity, "UTF-8"); } EntityUtils.consume(entity); // 釋放連接 response.close(); // System.out.println("body:" + body); } catch (Exception ex) { ex.printStackTrace(); } finally { try { client.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return body; } private static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException { SSLContext sc = SSLContext.getInstance("SSLv3"); // 實現一個X509TrustManager接口,用於繞過驗證,不用修改裏面的方法 X509TrustManager trustManager = new X509TrustManager() { @Override public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException { } @Override public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException { } @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } }; sc.init(null, new TrustManager[] { trustManager }, null); return sc; } private static class TrustAnyTrustManager implements X509TrustManager { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[] {}; } } private static class TrustAnyHostnameVerifier implements HostnameVerifier { public boolean verify(String hostname, SSLSession session) { return true; } } public static String sendSSLPostRequest(String url, String param) { PrintWriter out = null; BufferedReader in = null; String result = ""; try { // URLEncoder.encode(param,"UTF-8"); URL realUrl = new URL(url); URLConnection conn = realUrl.openConnection(); conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("Encoding", "utf-8"); conn.setRequestProperty("Charsert", "utf-8"); conn.setRequestProperty("Content-Type", "application/json"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); conn.setDoOutput(true); conn.setDoInput(true); if (conn instanceof HttpsURLConnection) { SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom()); ((HttpsURLConnection) conn).setSSLSocketFactory(sc.getSocketFactory()); ((HttpsURLConnection) conn).setHostnameVerifier(new TrustAnyHostnameVerifier()); } out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "utf-8")); out.print(param); out.flush(); in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("POST 請求異常!!!" + e); e.printStackTrace(); } finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { ex.printStackTrace(); } } return result; } }
全文完。dom
原文地址:socket