I am trying to save a file from URL using outputstream. The URL is secure by https. So I got some error when I try to get the file as the following
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
Suppose that I want to open the file from this URL
https://www.filepicker.io/api/file/KW9EJhYtS6y48Whm2S6D?signature=4098f262b9dba23e4766ce127353aaf4f37fde0fd726d164d944e031fd862c18&policy=eyJoYW5kbGUiOiJLVzlFSmhZdFM2eTQ4V2htMlM2RCIsImV4cGlyeSI6MTUwODE0MTUwNH0=
So I do something like:
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();
}
The result is nothing happen in the dedicated floder because the error is show up. How can I get the file from the HTTPS url?
The cause of the error is that Java cannot confirm the validity of the certificate. This can be fixed by importing the certificate into the JAVA certificate storage, or "fixed" by disabling SSL certificate validation.
A HTTPS connection requires handshaking. I.e. explicitly acknowledge each other. The server has identified itself by a HTTPS certificate, but you apparently don't have this certificate in your trust store and you are nowhere in your Java code explicitly acknowledging the identification, so the
HttpsURLConnection
(which is being used under the covers here) refuses to continue the HTTPS request.As a kickoff example, you can use the following piece of code in your class to let
HttpsURLConnection
accept all SSL certificates, regardless of the HTTPS URL you use.If you however want more fine grained control on a per-certificate basis, then implement the methods accordingly as per their Javadoc.
Unrelated to the concrete problem, you've a second problem in your code. You're attempting to save it the downloaded file as a folder instead of as a file.
Apart from the syntax error which is more likely result of carelessness during formulating the question (i.e. editing the code straight in question instead of actually copypasting working code), this isn't making any sense. You should not specify a folder as save location. You should specify a file name. You can if necessary extract it from the
Content-Disposition
header, or autogenerate one withFile#createTempFile()
. E.g.(and if you're already on Java 7, just make use of
Files#copy()
instead of that boilerplate)