Creating ZIP archives in Google App Engine ( Java)

2019-04-01 18:04发布

I am trying to clone a template ( folder with nested sub-folders) , replace a few files , ZIP it up and serve it to the user. Can this be done in App Engine since there is no local storage?

*** UPDATE**** The difficulty there was to build out a directory structure in memory and then zipping it up. Fortunately I found this post on stackoverflow : java.util.zip - Recreating directory structure

The rest is trivial.

thanks All,

1条回答
Deceive 欺骗
2楼-- · 2019-04-01 18:39

Yes, this can be done.

As I understand you, you want to serve a zip file. You don't need to save a zip file prior it is sent to the client as the response of a servlet. You can send the zip file directly to the client as it is generated / on-the-fly. (Note that AppEngine will cache the response and send it as the whole when your response is ready, but that's irrelevant here.)

Set the content type to application/zip, and you can create and send the response zip file by instantiating a ZipOutputStream passing the servlet's output stream as a constructor parameter.

Here's an example how to do it with an HttpServlet:

@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws
        ServletException, IOException {
    // Process parameters and do other stuff you need

    resp.setContentType("application/zip");
    // Indicate that a file is being sent back:
    resp.setHeader("Content-Disposition", "attachment;filename=template.zip");

    try (ZipOutputStream out = new ZipOutputStream(resp.getOutputStream())) {
        // Here go through your template / folders / files, optionally 
        // filter them or replace them with the content you want to include

        // Example adding a file to the output zip file:
        ZipEntry e = new ZipEntry("some/folder/image.png");
        // Configure the zip entry, the properties of the file
        e.setSize(1234);
        e.setTime(System.currentTimeMillis());
        // etc.
        out.putNextEntry(e);
        // And the content of the file:
        out.write(new byte[1234]);
        out.closeEntry();

        // To add another file to the output zip,
        // call putNextEntry() again with the entry,
        // write its content with the write() method and close with closeEntry().

        out.finish();
    } catch (Exception e) {
        // Handle the exception
    }
}

Note: You might wanna disable caching of your response zip file, depending on your case. If you want to disable caching the result by proxies and browsers, add these lines before you start the ZipOutputStream:

resp.setHeader("Cache-Control", "no-cache"); // For HTTP 1.1
resp.setHeader("Pragma", "no-cache"); // For HTTP 1.0
resp.setDateHeader("Expires", 0); // For proxies
查看更多
登录 后发表回答