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:1949) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1514) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026) at sun.security.ssl.Handshaker.process_record(Handshaker.java:961) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:747) at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)异常原因
本地没有可用的证书,导致SSL校验失败
解决方案- 安装证书
- 通过代码方式忽略证书(可以临时用,不推荐长期使用,存在安全性问题)
1- 工具类
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 SslUtils { private static void trustAllHttpsCertificates() throws Exception { TrustManager[] trustAllCerts = new TrustManager[1]; TrustManager tm = new miTM(); trustAllCerts[0] = tm; SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, null); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } static class miTM implements TrustManager,X509TrustManager { public X509Certificate[] getAcceptedIssuers() { return null; } public boolean isServerTrusted(X509Certificate[] certs) { return true; } public boolean isClientTrusted(X509Certificate[] certs) { return true; } public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException { return; } public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException { return; } } public static void ignoreSsl() throws Exception{ HostnameVerifier hv = new HostnameVerifier() { //实现自己的脚丫逻辑,这里就直接返回true,不进行校验 public boolean verify(String urlHostName, SSLSession session) { System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost()); return true; } }; trustAllHttpsCertificates(); HttpsURLConnection.setDefaultHostnameVerifier(hv); } }
2-URL请求封装
import java.io.OutputStreamWriter; import java.net.URL; import java.net.URLConnection; import org.apache.commons.io.IOUtils; public class SslTest { public String getRequest(String url,int timeOut) throws Exception{ URL u = new URL(url); if("https".equalsIgnoreCase(u.getProtocol())){ SslUtils.ignoreSsl(); } URLConnection conn = u.openConnection(); conn.setConnectTimeout(timeOut); conn.setReadTimeout(timeOut); return IOUtils.toString(conn.getInputStream()); } public String postRequest(String urlAddress,String args,int timeOut) throws Exception{ URL url = new URL(urlAddress); if("https".equalsIgnoreCase(url.getProtocol())){ SslUtils.ignoreSsl(); } URLConnection u = url.openConnection(); u.setDoInput(true); u.setDoOutput(true); u.setConnectTimeout(timeOut); u.setReadTimeout(timeOut); OutputStreamWriter osw = new OutputStreamWriter(u.getOutputStream(), "UTF-8"); osw.write(args); osw.flush(); osw.close(); u.getOutputStream(); return IOUtils.toString(u.getInputStream()); } public static void main(String[] args) { try { SslTest st = new SslTest(); String result = st.getRequest("https://www.baidu.com/", 3000); System.out.println(result); } catch (Exception e) { e.printStackTrace(); } } }
3.此处具体代码实现
package com.yjp.dubbo.service; import com.yjp.dubbo.pojp.User; import javax.net.ssl.HttpsURLConnection; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import java.io.*; import java.net.URL; public class TestConnection { public static void main(String[] args) throws Exception { OutputStreamWriter out = null ; BufferedReader in = null; StringBuilder result = new StringBuilder(); String url = "https://citic:30466/dsgj/"; File file = new File("D:\A.txt"); JAXBContext jbt = JAXBContext.newInstance(User.class); User user=new User(); user.setTRANS_CODE("21000001"); user.setREQ_SSN("J100330000000002018121715130000012300000"); user.setMCHNT_ID("J10033000000000"); user.setMCHNT_USER_ID("test1"); user.setUSER_TYPE("1"); user.setUSER_NM("联调测试"); user.setUSER_ROLE("001001"); user.setSIGN_TYPE("00"); user.setUSER_ID_TYPE("01"); user.setUSER_ID_NO("000013477"); user.setUSER_PHONE("15562632654"); user.setCORP_NM("李先生"); user.setCORP_ID_NO("123456"); user.setUSER_ADD("北京市青年路"); user.setREQ_RESERVED(""); user.setSIGN_INFO("00"); Marshaller ms = jbt.createMarshaller(); ms.marshal(user, file); in = new BufferedReader(new FileReader("D:\A.txt")); int b; StringBuilder param = new StringBuilder(); while((b=in.read())!=-1){ param.append((char) b); } System.out.print(param); System.out.println(""); System.out.println("-------------------------------------------------------");//此处对url进行post请求 try { URL realUrl = new URL(url); if("https".equalsIgnoreCase(realUrl.getProtocol())){ SslUtils.ignoreSsl(); } // 打开和URL之间的连接 HttpsURLConnection conn = (HttpsURLConnection)realUrl.openConnection(); //设置通用的请求头属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 发送POST请求必须设置如下两行 否则会抛异常(java.net.ProtocolException: cannot write to a URLConnection if doOutput=false - call setDoOutput(true)) conn.setDoOutput(true); conn.setDoInput(true); //获取URLConnection对象对应的输出流并开始发送参数 out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); //添加参数 out.write(param.toString()); out.flush(); in = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8")); String line; while ((line = in.readLine()) != null) { result.append(line); } } catch (Exception e) { e.printStackTrace(); }finally {// 使用finally块来关闭输出流、输入流 try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { ex.printStackTrace(); } } System.out.println(result.toString()); } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)