Servlet buffering response despite calls to flush()

前端 未结 6 555
盖世英雄少女心
盖世英雄少女心 2021-02-08 04:10

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

6条回答
  •  滥情空心
    2021-02-08 04:35

    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 each containing a single line 100 characters wide and ending with . This is on Windows 7 Premium 64 with JDK 1.6.0_26. Chrome acts the same way. IE, on the other hand, seems to normally wait for 5 seconds (500 bytes), though once it showed the dialog immediately, and another time it seemed to wait for 9 or 10 seconds. Try it in different browsers:

    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);
                }
            }
        }
    }
    

提交回复
热议问题