We have a system where a client makes an HTTP GET request, the system does some processing on the backend, zips the results, and sends it to the client. Since the processing can
I entirely can't reproduce your problem. Below is your code, slightly altered, running in an embedded Jetty server. I ran it in IntelliJ and requested http://localhost:8080 from Firefox. As expected, the "Save or Open" dialog popped up after 1 second. Selecting "save" and waiting for 20 seconds results in a zip file which can be opened and contains 20 separate entries, named foo
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZippingAndStreamingServlet {
public static void main(String[] args) throws Exception {
Server server = new Server(8080);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
context.addServlet(new ServletHolder(new BufferingServlet()), "/*");
server.start();
System.out.println("Listening on 8080");
server.join();
}
static class BufferingServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
ZipOutputStream _zos = new ZipOutputStream(response.getOutputStream());
ZipEntry _ze;
long startTime = System.currentTimeMillis();
long _lByteCount = 0;
int count = 1;
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=my.zip");
while (_lByteCount < 2000) {
_ze = new ZipEntry("foo" + count);
_zos.putNextEntry(_ze);
byte[] bytes = String.format("%100d", count++).getBytes();
System.out.println("Sending " + bytes.length + " bytes");
_zos.write(bytes);
_lByteCount += bytes.length;
sleep(1000);
System.out.println("Zip: " + _lByteCount + " Time: " + ((System.currentTimeMillis() - startTime) / 1000));
_zos.flush();
}
_zos.close();
}
private void sleep(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
throw new IllegalStateException("Unexpected interrupt!", e);
}
}
}
}