Skip to content
Advertisement

How do I work with a REST API in Java that returns a zip file?

I am familiar with the basics of making a GET request in Java using the HttpURLConnection class. In a normal situation where the return type would be a JSON, I’d do something like this:

    URL obj = new URL(myURLString);
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("GET");
    int responseCode = con.getResponseCode();
    if (responseCode == HttpURLConnection.HTTP_OK) {
        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inpLine;
        StringBuffer resp = new StringBuffer();

        while ((inpLine = in.readLine()) != null) {
            resp.append(inputLine);
        }
        in.close();
        System.out.println(resp.toString());                          
    } else { System.out.println("Request failed");

However, the current endpoint I’m trying to work with sends back a zip file containing various types of files. The ‘Content-Type’ in that case would be ‘application/octet-stream’. Hitting that endpoint with the above code results in a mess of symbols (not sure what it’s called) written to the console. Even in Postman, I see the same, and it only works when I use the ‘Send & Download’ option when making the request, which prompts me to save the response and I get the zip file.

Any help on how to hit the API and download the returned zip file through Java? Thank you in advance.

Edit: What I intend to do with the zip file is save it locally and then other parts of my program will work with the contents.

Advertisement

Answer

I guess you can try this API:

try (ZipInputStream zis = new ZipInputStream(con.getInputStream())) {
        
    ZipEntry entry; // kinda self-explained (a file inside zip)

    while ((entry = zis.getNextEntry()) != null) {
         // do whatever you need :)
         // this is just a dummy stuff
        System.out.format("File: %s Size: %d Last Modified %s %n",
                    entry.getName(), entry.getSize(),
                    LocalDate.ofEpochDay(entry.getTime() / MILLS_IN_DAY));
    }
}

In any case, you get a stream, so you can do all the stuff that java IO API allows you to do.

For instance, to save the file you can do something like:

// I am skipping here exception handling, closing stream, etc.
byte[] zipContent = zis.readAllBytes();
new FileOutputStream("some.zip").write(zipContent);

To do something with files inside zip you can do something like:

 // again, skipping exceptions, closing, etc.
 // also, you'd probably do this in while loop as in the first example
 // so let's say we get ZipEntry 
 ZipEntry entry = zis.getNextEntry();
 
 // crate OutputStream to extract the entry from zip file
 final OutputStream os = new FileOutputStream("c:/someDir/" + entry.getName());
 
 
 byte[] buffer = new byte[1024];
 int length;
 
 //read the entry from zip file and extract it to disk
 while( (length = zis.read(buffer)) > 0) {
     os.write(buffer, 0, length);
 }

 // at this point you should get your file

I know, this is kinda low level API, you need to deal with streams, bytes, etc., perhaps there are some libs that allows to do this with a single line of code or something 🙂

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement