java在访问https资源时的证书信任问题

java程序在访问https资源时,出现报错html

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请求相比,多了红色的部分,不忽略证书信任的代码能够参考我另一篇博客:java

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

就是在进行链接前须要显示调用如下进行忽略证书信任:session

trustAllHttpsCertificates();    // 这是一个方法,具体见上面
HttpsURLConnection.setDefaultHostnameVerifier(hv);        //这里HttpsURLConnection是类名,hv参数须要本身建立,具体能够参考上面。

Post请求须要忽略证书信任与这个同样,在获取链接前,加上以上代码。ide

相关文章
相关标签/搜索