用httpclient访问https 资源时,会出现异常,与环境也有关系,有些机器请求正常.
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 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1623) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:198) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:192) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1074) at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:128) at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:529) at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:465) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1120) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1147) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1131) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1049) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234) at com.msd.payCenter.msdPay.yeePay.util.HttpUtils.URLGet(HttpUtils.java:67) at com.msd.payCenter.msdPay.yeePay.service.impl.YeePayServiceImpl.yeeAutoCheckOrder(YeePayServiceImpl.java:298) at com.msd.payCenter.msdPay.AutoCheckOrderServiceImpl.autoCheckOrder(AutoCheckOrderServiceImpl.java:83) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
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 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1623) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:198) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:192) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1074) at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:128) at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:529) at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:465) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1120) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1147) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1131) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1049) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234) at com.msd.payCenter.msdPay.yeePay.util.HttpUtils.URLGet(HttpUtils.java:67) at com.msd.payCenter.msdPay.yeePay.service.impl.YeePayServiceImpl.yeeAutoCheckOrder(YeePayServiceImpl.java:298) at com.msd.payCenter.msdPay.AutoCheckOrderServiceImpl.autoCheckOrder(AutoCheckOrderServiceImpl.java:83) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
解决方法:
增加一个自己的https协议类 MySSLSocketFactory.java
package com.nassir.hc3; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.net.UnknownHostException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.SocketFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.commons.httpclient.ConnectTimeoutException; import org.apache.commons.httpclient.params.HttpConnectionParams; import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; public class MySSLSocketFactory implements ProtocolSocketFactory { static { System.out.println(">>>>in MySSLSocketFactory>>"); } private SSLContext sslcontext = null; private SSLContext createSSLContext() { SSLContext sslcontext = null; try { sslcontext = SSLContext.getInstance("SSL"); sslcontext.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } return sslcontext; } private SSLContext getSSLContext() { if (this.sslcontext == null) { this.sslcontext = createSSLContext(); } return this.sslcontext; } public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose); } public Socket createSocket(String host, int port) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket(host, port); } public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort); } public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException { if (params == null) { throw new IllegalArgumentException("Parameters may not be null"); } int timeout = params.getConnectionTimeout(); SocketFactory socketfactory = getSSLContext().getSocketFactory(); if (timeout == 0) { return socketfactory.createSocket(host, port, localAddress, localPort); } else { Socket socket = socketfactory.createSocket(); SocketAddress localaddr = new InetSocketAddress(localAddress, localPort); SocketAddress remoteaddr = new InetSocketAddress(host, port); socket.bind(localaddr); socket.connect(remoteaddr, timeout); return socket; } } 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[] {}; } } }
package com.nassir.hc3; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.net.UnknownHostException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.SocketFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.commons.httpclient.ConnectTimeoutException; import org.apache.commons.httpclient.params.HttpConnectionParams; import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; public class MySSLSocketFactory implements ProtocolSocketFactory { static { System.out.println(">>>>in MySSLSocketFactory>>"); } private SSLContext sslcontext = null; private SSLContext createSSLContext() { SSLContext sslcontext = null; try { sslcontext = SSLContext.getInstance("SSL"); sslcontext.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } return sslcontext; } private SSLContext getSSLContext() { if (this.sslcontext == null) { this.sslcontext = createSSLContext(); } return this.sslcontext; } public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose); } public Socket createSocket(String host, int port) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket(host, port); } public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort); } public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException { if (params == null) { throw new IllegalArgumentException("Parameters may not be null"); } int timeout = params.getConnectionTimeout(); SocketFactory socketfactory = getSSLContext().getSocketFactory(); if (timeout == 0) { return socketfactory.createSocket(host, port, localAddress, localPort); } else { Socket socket = socketfactory.createSocket(); SocketAddress localaddr = new InetSocketAddress(localAddress, localPort); SocketAddress remoteaddr = new InetSocketAddress(host, port); socket.bind(localaddr); socket.connect(remoteaddr, timeout); return socket; } } 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[] {}; } } }
请求类:
/** * */ package com.nassir.hc3; import java.io.IOException; import java.io.InputStream; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.protocol.Protocol; /** * @author nassir wen * @data 2012-3-31 下午05:09:13 * @version V2.5 * @Company: MSD. * @Copyright Copyright (c) 2012 */ public class HttpsRequest { /** * * @param url * @return */ public static String post(String url) { //增加下面两行代码 Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443); Protocol.registerProtocol("https", myhttps); HttpClient client = new HttpClient(); HttpMethod post = new PostMethod(url); try { client.executeMethod(post); byte[] responseBody = post.getResponseBody(); String result = new String(responseBody,"GBK"); return result; } catch (HttpException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { post.releaseConnection(); } return null; } }
/** * */ package com.nassir.hc3; import java.io.IOException; import java.io.InputStream; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.protocol.Protocol; /** * @author nassir wen * @data 2012-3-31 下午05:09:13 * @version V2.5 * @Company: MSD. * @Copyright Copyright (c) 2012 */ public class HttpsRequest { /** * * @param url * @return */ public static String post(String url) { //增加下面两行代码 Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443); Protocol.registerProtocol("https", myhttps); HttpClient client = new HttpClient(); HttpMethod post = new PostMethod(url); try { client.executeMethod(post); byte[] responseBody = post.getResponseBody(); String result = new String(responseBody,"GBK"); return result; } catch (HttpException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { post.releaseConnection(); } return null; } }
测试:
public static void main(String[] args) { System.out.println(HttpsRequest.post("https://www.alipay.com"));//支付宝做测试 }
public static void main(String[] args) { System.out.println(HttpsRequest.post("https://www.alipay.com"));//支付宝做测试 }