From: https://www.cnblogs.com/luoxiao1104/p/16671501.html
当我们从网络上根据url下载文件的时候可能会出现一下异常
错误信息:
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
问题原因:
在Java8及高版本以上的版本在源应用程序不信任目标应用程序的证书,因为在源应用程序的JVM信任库中找不到该证书或证书链。也就是目标站点启用了HTTPS 而缺少安全证书时出现的异常
常见的解决方法有三种:
1. 手动生成证书;
2. 忽略证书验证。(建议使用)
3. 在JDK安装目录中删除
三种方式的实现:
1、手动导入安全证书
手动生成证书方法参考大佬博客:手动生成证书方法
2、忽略证书验证(建议使用)
public class Base64Util {
public static String getBase64FromUrl(String fileUrl) {
InputStream inputStream = null;
byte[] data = null;
ByteArrayOutputStream swapStream = null;
HttpsURLConnection conn = null;
try {
URL url = new URL(fileUrl);
//判断当前文件url是否是https
if (fileUrl.contains("https:")){
//是https
//绕过证书
SSLContext context = createIgnoreVerifySSL();
conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(context.getSocketFactory());
inputStream = conn.getInputStream();
}else {
//当前链接是http
inputStream = url.openConnection().getInputStream();
}
swapStream = new ByteArrayOutputStream();
byte[] buff = new byte[100];
int rc = 0;
while ((rc = inputStream.read(buff, 0, 100)) > 0) {
swapStream.write(buff, 0, rc);
}
data = swapStream.toByteArray();
} catch (Exception e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(swapStream);
}
return new String(Base64.encodeBase64(data));
}
//绕过SSL、TLS证书
public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sc = SSLContext.getInstance("TLS");
// 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sc.init(null, new TrustManager[]{trustManager}, null);
return sc;
}
}
3、删除JDK安装目录下jre/lib/security的java.security
文件的SSLv3, TLSv1, TLSv1.1
,(不建议使用,本地环境和生产环境不一样)
------------------------ 以下为个人整理的一个文件下载的工具类,仅供参考 ----------------------
开发环境:Windows 10 + JDK21
package com.ruoyi.common.util; import cn.hutool.core.io.FileUtil; import lombok.Data; import lombok.extern.slf4j.Slf4j; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.io.*; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; @Data @Slf4j public class FileDownloader { private String saveDir; // 服务器上文件存储目录 public FileDownloader(String saveDir) { this.saveDir = saveDir; } private String getSavePath(String fileName) { return saveDir + "/" + fileName; } public int download(String remoteFileUrl) { InputStream is; try { // 构造URL URL url = new URL(remoteFileUrl); // 打开连接 URLConnection con = url.openConnection(); // 设置请求头 con.addRequestProperty("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"); // 设置请求超时为5s con.setConnectTimeout(5 * 1000); if (remoteFileUrl.startsWith("https:")) { SSLContext context = createIgnoreVerifySSL(); con = url.openConnection(); ((HttpsURLConnection) con).setSSLSocketFactory(context.getSocketFactory()); } is = con.getInputStream(); // 1K的数据缓冲 byte[] bs = new byte[1024]; // 读取到的数据长度 int len; // 输出的文件流 String name = FileUtil.getName(remoteFileUrl); var savepath = getSavePath(name); var dir = new File(saveDir); if (!dir.exists()) { dir.mkdirs(); } OutputStream os = new FileOutputStream(savepath); // 开始读取 while ((len = is.read(bs)) != -1) { os.write(bs, 0, len); } // 完毕,关闭所有链接 os.close(); is.close(); return 1; } catch (MalformedURLException e) { e.printStackTrace(); } catch (FileNotFoundException e) { System.out.println("下载文件路径不存在:" + remoteFileUrl); } catch (IOException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } catch (KeyManagementException e) { throw new RuntimeException(e); } return 0; } /** * 参考: https://www.cnblogs.com/luoxiao1104/p/16671501.html * 在Java8及高版本以上的版本在源应用程序不信任目标应用程序的证书,因为在源应用程序的JVM信任库中找不到该证书或证书链。也就是目标站点启用了HTTPS 而缺少安全证书时出现的异常 * * @return * @throws NoSuchAlgorithmException * @throws KeyManagementException */ public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException { SSLContext sc = SSLContext.getInstance("TLS"); // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法 X509TrustManager trustManager = new X509TrustManager() { @Override public void checkClientTrusted( java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException { } @Override public void checkServerTrusted( java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException { } @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } }; sc.init(null, new TrustManager[]{trustManager}, null); return sc; } }
标签:building,java,String,failed,PKIX,import,new,security,public From: https://www.cnblogs.com/joeblackzqq/p/18089615