`
atell
  • 浏览: 158968 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

下载功能,当用户点击下载,弹出“保存,取消”的框后,如果用户不做任何点击,此时,服务器servlet的out.write不会hold住

阅读更多
package com.demo;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

public class DownloadServlet extends HttpServlet {

    public static Logger      log              = Logger.getLogger(DownloadServlet.class);

    private static final long serialVersionUID = 1L;

    /**
     * 实验:下载功能,当用户点击下载,弹出“保存,取消”的框后,如果用户不做任何点击,<br>
     * 此时,服务器servlert的out.write是会hold住吗? 还是能继续输出?
     * http://topic.csdn.net/u/20110915/09/7f162e68-7632-4985-9aab-920bb06df2cc
     * .html?seed=1489779347&r=75525057#r_75525057
     * 
     * (错误,请忽略)飞飞说,应该是cache在操作系统中(Socket内核相关)。我write了260M数据,看到java占用内存还是70M,所以确实有可能。
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置响应头信息,下载的文件
        String contentType = "application/octet-stream;charset=GBK";
        String contentDisposition = "attachment; filename=\"demo.txt\"";
        response.setContentType(contentType);
        response.setHeader("Content-disposition", contentDisposition);
        
        //response buffer
        log.error(response.getBufferSize());
        response.setBufferSize(1);
        log.error(response.getBufferSize());

        OutputStream os = response.getOutputStream();
        PrintWriter pw = new PrintWriter(os);
        Long i = 0L;
        while (i++ < 10000000L) {// 260M的文件
            pw.println("some test content.........");//
            pw.flush();
        }
        pw.close();
//        response.

        
        
        // 即使不点击“保存”,也不会hold住,会继续输出下列log。而且,隔了30分钟后再点击“保存”,竟然还能下载成功。
        log.error("outputstream closed! come here!");

    }

}

 

demo见附件。

 

 

结论:

曹帅解答了我的疑惑,只要用户点击了下载资源的Url,无论用户是否点击“保 存”,浏览器会马上开始下载完整的response的(使用httpfox看确实是这样,我没点击“保存”它就已经下载完文件了),不管你是否点击保存, 保存的行为只是浏览器将下载完或正在下载的内容存到用户指定的文件中而已。( 再说,HTTP协议本身就是request/response,不可能还能根据用户是否点击保存的行为而Hold住的。) 同时,想想wget,是直接就下载吧,没有hold的。

 

 

20120301补充:后来验证过,ie和firefox行为不一样,iE会hold住。看来。。。结论还是:因浏览器而异!

(IE这么做,我一开始觉得不对劲,但是后来觉得还是合理的,想想做web im常用的comet方式,就是js在浏览器端发起请求,服务端若无数据就Blocked几十秒再返回响应。http没谈到请求/响应的时间间隙,故在请求和响应过程中,其中一方选择blocked,导致tcp暂时无数据传输(除了滑动窗口心跳通讯),也是合理的)

 

2
1
分享到:
评论
4 楼 xunke515 2014-12-24  
* firefox 31,不会hold,请求后服务器直接传输数据.客户端弹出,保存或者取消确认框得时候也会传输数据的</br>
* chrome 34 直接下载,不弹出确认和取消的弹框</br>
* 亲测:ie 10 行为跟firefox31类似</br>
3 楼 ccqqct 2012-10-26  
IE更烂,他不是hold住了,他会向服务器发起两次请求,服务器处理两次。  如果用于批量提交并返回处理结果你就知道后果了。
2 楼 samttsch 2011-09-15  
点击取消 浏览器应该会反馈给server做处理吧

个人猜想:不点击确定,也不取消,浏览器还是会缓存起来

只是不知道这个如何证明这个逻辑
1 楼 孔已己 2011-09-15  
有点意思,可以试试

相关推荐

Global site tag (gtag.js) - Google Analytics