When using HttpURLConnection to link https resources, the verification fails and the error is reported as follows:
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:1964) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:328) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:322) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1614) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1052) at sun.security.ssl.Handshaker.process_record(Handshaker.java:987) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:162) at com.lovnx.note.rabbitmq.listener.ThreeCallBackListener.downLoadFromUrl(ThreeCallBackListener.java:338) at com.lovnx.note.rabbitmq.listener.ThreeCallBackListener.main(ThreeCallBackListener.java:468) Caused by: 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.validator.PKIXValidator.doBuild(PKIXValidator.java:397) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302) at sun.security.validator.Validator.validate(Validator.java:262) at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1596) ... 12 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392) ... 18 more Process finished with exit code 0
solve
public static void downLoadFromUrl(String urlStr, String fileName, String savePath) throws IOException { URL url = new URL(urlStr); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); boolean useHttps = urlStr.startsWith("https"); if (useHttps) { HttpsURLConnection https = (HttpsURLConnection) conn; trustAllHosts(https); https.setHostnameVerifier(DO_NOT_VERIFY); } //Set the timeout to 3 seconds conn.setConnectTimeout(3 * 1000); //Prevent blocking programs from crawling and returning a 403 error conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); conn.setDoInput(true); conn.connect(); //Get the input stream InputStream inputStream = conn.getInputStream(); //Get own array byte[] getData = readInputStream(inputStream); //file save location File saveDir = new File(savePath); if (!saveDir.exists()) { saveDir.mkdir(); } File file = new File(saveDir + File.separator + fileName); FileOutputStream fos = new FileOutputStream(file); fos.write(getData); if (fos != null) { fos.close(); } if (inputStream != null) { inputStream.close(); } status = true; log.info("pdfUrl file download, url=[{}], save address=[{}], file name=[{}]", url, savePath, fileName); } /** * Override java's default certificate verification */ private static final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new java.security.cert.X509Certificate[]{}; } @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } }}; /** * Set not to verify the host */ private static final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }; /** *Trust all * @param connection * @return */ private static SSLSocketFactory trustAllHosts(HttpsURLConnection connection) { SSLSocketFactory oldFactory = connection.getSSLSocketFactory(); try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); SSLSocketFactory newFactory = sc.getSocketFactory(); connection.setSSLSocketFactory(newFactory); } catch (Exception e) { e.printStackTrace(); } return oldFactory; }
test
public static void main(String[] args) { try { downLoadFromUrl("https://file path", "Baidu.pdf", "temp/"); } catch (Exception e) { e.printStackTrace(); // TODO: handle exception } }
This is it. Modify the https path to obtain the file and download it.
Reference link: https://www.jianshu.com/p/a928b6c34f06