javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building f

今天公司测试第三方接口,这个接口是用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;
        }
    }
}

完美解决

猜你喜欢

转载自blog.csdn.net/lwang_it/article/details/79985039