Tak*_*umi 0 java https outputstream httpurlconnection filepicker.io
我正在尝试使用outputstream从URL保存文件.该URL由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 sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
at java.net.URL.openStream(Unknown Source)
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
... 60 more
Run Code Online (Sandbox Code Playgroud)
假设我想从这个URL打开文件
https://www.filepicker.io/api/file/KW9EJhYtS6y48Whm2S6D?signature=4098f262b9dba23e4766ce127353aaf4f37fde0fd726d164d944e031fd862c18&policy=eyJoYW5kbGUiOiJLVzlFSmhZdFM2eTQ4V2htMlM2RCIsImV4cGlyeSI6MTUwODE0MTUwNH0=
Run Code Online (Sandbox Code Playgroud)
所以我做了类似的事情:
try{
URL URL = new URL('https://www.filepicker.io/api/file/KW9EJhYtS6y48Whm2S6D?signature=4098f262b9dba23e4766ce127353aaf4f37fde0fd726d164d944e031fd862c18&policy=eyJoYW5kbGUiOiJLVzlFSmhZdFM2eTQ4V2htMlM2RCIsImV4cGlyeSI6MTUwODE0MTUwNH0=');
String = path = "D://download/";
InputStream ins = url.openStream();
OutputStream ous = new FileOutputStream(path);
final byte[] b = new byte[2048];
int length;
while ((length = inputStream.read(b)) != -1) {
ous.write(b, 0, length);
}
ins.close();
ous.close();
}
Run Code Online (Sandbox Code Playgroud)
结果是在专用floder中没有发生任何事情,因为错误出现了.如何从HTTPS网址获取文件?
Bal*_*usC 13
HTTPS连接需要握手.即明确承认彼此.服务器已通过HTTPS证书标识自己,但您显然在您的信任存储中没有此证书,并且您在Java代码中没有明确承认该标识,因此HttpsURLConnection
(在此处使用的内容)拒绝继续HTTPS请求.
作为启动示例,您可以使用类中的以下代码来HttpsURLConnection
接受所有SSL证书,无论您使用何种HTTPS URL.
static {
final TrustManager[] trustAllCertificates = new TrustManager[] {
new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null; // Not relevant.
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
// Do nothing. Just allow them all.
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
// Do nothing. Just allow them all.
}
}
};
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCertificates, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (GeneralSecurityException e) {
throw new ExceptionInInitializerError(e);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果您希望在每个证书的基础上进行更细粒度的控制,则根据其Javadoc相应地实现这些方法.
与具体问题无关,您的代码中存在第二个问题.您试图将下载的文件另存为文件夹而不是文件.
String = path = "D://download/";
OutputStream ous = new FileOutputStream(path);
Run Code Online (Sandbox Code Playgroud)
除了语法错误之外,更有可能是在制定问题时粗心大意(即直接编辑代码而不是实际复制工作代码),这没有任何意义.您不应将文件夹指定为保存位置.您应该指定文件名.如有必要,您可以从Content-Disposition
标题中提取它,或者使用自动生成标题File#createTempFile()
.例如
File file = File.createTempFile("test-", ".jpg", new File("D:/download/"));
Files.copy(url.openStream(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
Run Code Online (Sandbox Code Playgroud)
(如果你已经在Java 7上,只需使用Files#copy()
而不是那个样板)
归档时间: |
|
查看次数: |
6284 次 |
最近记录: |