HTTP-java訪問https資源時,忽略證書信任問題,代碼栗子


java程序在訪問https資源時,出現報錯

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
這本質上,是java在訪問https資源時的證書信任問題。如何解決這個問題呢?
關於這個問題有一篇博客做了很詳細的解釋,需要理解的可以查看: http://blog.csdn.net/lizeyang/article/details/18983843
 
以下是結合我具體情況的一個小栗子:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;

import org.apache.log4j.Logger;
import org.htmlparser.util.ParserException;

import com.xwtech.parser.GetRequestHtmlParser;
import com.xwtech.pojo.ExtendCandidate;
/*
 * GET請求類
 */
public class GetRequest {
    private String url = "https://b2b.10086.cn/b2b/main/viewNoticeContent.html?noticeBean.id=";
    private Logger logger;
    public GetRequest() {
        logger = Logger.getLogger(GetRequest.class);
    }
    private static void trustAllHttpsCertificates() throws Exception {
        javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
        javax.net.ssl.TrustManager tm = new miTM();
        trustAllCerts[0] = tm;
        javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, null);
        javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    }
    //為更好的演示,去掉了不相關的代碼
    public void getData(String id) {
        this.url = url + id;
        BufferedReader in = null;
        HttpURLConnection conn = null;
        String result = "";
        try {
        //該部分必須在獲取connection前調用 trustAllHttpsCertificates(); HostnameVerifier hv
= new HostnameVerifier() { public boolean verify(String urlHostName, SSLSession session) { logger.info("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost()); return true; } }; HttpsURLConnection.setDefaultHostnameVerifier(hv); conn = (HttpURLConnection)new URL(url).openConnection(); // 發送GET請求必須設置如下兩行 conn.setDoInput(true); conn.setRequestMethod("GET"); // flush輸出流的緩沖 in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { logger.error("發送 GET 請求出現異常!\t請求ID:"+id+"\n"+e.getMessage()+"\n"); } finally {// 使用finally塊來關閉輸出流、輸入流 try { if (in != null) { in.close(); } } catch (IOException ex) { logger.error("關閉數據流出錯了!\n"+ex.getMessage()+"\n"); } } // 獲得相應結果result,可以直接處理...... } static class miTM implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) { return true; } public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) { return true; } public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException { return; } public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException { return; } } }

與正常get請求相比,多了紅色的部分,不忽略證書信任的代碼可以參考我另外一篇博客:

  http://www.cnblogs.com/husky/p/6377577.html

就是在進行連接前需要顯示調用以下進行忽略證書信任:

trustAllHttpsCertificates();    // 這是一個方法,具體見上面
HttpsURLConnection.setDefaultHostnameVerifier(hv);        //這里HttpsURLConnection是類名,hv參數需要自己創建,具體可以參考上面。

Post請求需要忽略證書信任與這個一樣,在獲取連接前,加上以上代碼。

相關文章:

  java實現Get請求: http://www.cnblogs.com/husky/p/6377577.html

  java實現Post請求: http://www.cnblogs.com/husky/p/6377553.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM