Download images from a HTTPS URL in Java

2019-06-08 07:39发布

问题:

I have to do an application that shows an image of the medication packages. I've found this site that have some, but I'm trying to download the available images with a little program in Java but fails. I think HTTPS causes the issue.

There's a way to do it?

EDIT: code and error

public class DescargarArchivo {

public static void main(String[] args) {
    String url = "https://medicamentos.sanidadmadrid.org/comun/visorCaratulas.aspx?cod=672629";
    String name = "test.jpg";

    String folder = "downloads/";

    File dir = new File(folder);

    if (!dir.exists())
            if (!dir.mkdir())
                    return;

    File file = new File(folder + name);

    try {

            URLConnection conn = new URL(url).openConnection();
            conn.connect();

            System.out.println("\ndownload: \n");
            System.out.println(">> URL: " + url);
            System.out.println(">> Name: " + name);
            System.out.println(">> size: " + conn.getContentLength()
                            + " bytes");

            InputStream in = conn.getInputStream();
            OutputStream out = new FileOutputStream(file);

            int b = 0;

            while (b != -1) {
                    b = in.read();

                    if (b != -1)
                            out.write(b);
            }

            out.close();
            in.close();

            System.out.println("\ncomplete download\n");
    } catch (MalformedURLException e) {
            System.out.println("url: " + url + " invalid");
    } catch (IOException e) {
            e.printStackTrace();
    }
}
}

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 sun.security.ssl.Handshaker.processLoop(Unknown Source)
at sun.security.ssl.Handshaker.process_record(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(Unknown Source)
at com.test.java.net.DescargarArchivo.main(DescargarArchivo.java:34)
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(Unknown Source)
    at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
    at sun.security.validator.Validator.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
    ... 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(Unknown Source)
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
    at java.security.cert.CertPathBuilder.build(Unknown Source)
    ... 18 more

回答1:

You need to set the permission to allow the server certificate. Here it explains how to set so that all cert are trusted.



回答2:

Actually I had the similar problem. I was unable to download files from HTTPS server. Then I fixed this problem with this solution:

// But are u denied access?
// well here is the solution.
public static void TheKing_DownloadFileFromURL(String search, String path) throws IOException {

    // This will get input data from the server
    InputStream inputStream = null;

    // This will read the data from the server;
    OutputStream outputStream = null;

    try {
        // This will open a socket from client to server
        URL url = new URL(search);

        // This user agent is for if the server wants real humans to visit
        String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36";

        // This socket type will allow to set user_agent
        URLConnection con = url.openConnection();

        // Setting the user agent
        con.setRequestProperty("User-Agent", USER_AGENT);

        //Getting content Length
        int contentLength = con.getContentLength();
        System.out.println("File contentLength = " + contentLength + " bytes");


        // Requesting input data from server
        inputStream = con.getInputStream();

        // Open local file writer
        outputStream = new FileOutputStream(path);

        // Limiting byte written to file per loop
        byte[] buffer = new byte[2048];

        // Increments file size
        int length;
        int downloaded = 0; 

        // Looping until server finishes
        while ((length = inputStream.read(buffer)) != -1) 
        {
            // Writing data
            outputStream.write(buffer, 0, length);
            downloaded+=length;
            //System.out.println("Downlad Status: " + (downloaded * 100) / (contentLength * 1.0) + "%");


        }
    } catch (Exception ex) {
        //Logger.getLogger(WebCrawler.class.getName()).log(Level.SEVERE, null, ex);
    }

    // closing used resources
    // The computer will not be able to use the image
    // This is a must
    outputStream.close();
    inputStream.close();
}

Hope this helps.... :)