如何强制浏览器下载文件?

die*_*ing 54 java servlets java-ee

一切正常,但只有文件很小,大约1MB,当我尝试使用更大的文件,比如20MB我的浏览器显示它,而不是强行下载,到目前为止我尝试了很多标题,现在我的代码看起来:

PrintWriter out = response.getWriter();
String fileName = request.getParameter("filename");

File f= new File(fileName);

InputStream in = new FileInputStream(f);
BufferedInputStream bin = new BufferedInputStream(in);
DataInputStream din = new DataInputStream(bin);

while(din.available() > 0){
    out.print(din.readLine());
    out.print("\n");
}

response.setContentType("application/force-download");
response.setContentLength((int)f.length());
response.setHeader("Content-Transfer-Encoding", "binary");
response.setHeader("Content-Disposition","attachment; filename=\"" + "xxx\"");//fileName);


in.close();
bin.close();
din.close();
Run Code Online (Sandbox Code Playgroud)

Vin*_*lds 65

在将文件内容写入输出流后设置响应标头.这在设置标头的响应生命周期中已经很晚了.正确的操作顺序应该是首先设置标头,然后将文件的内容写入servlet的输出流.

因此,您的方法应该写成如下(这不会编译,因为它只是一个表示):

response.setContentType("application/force-download");
response.setContentLength((int)f.length());
        //response.setContentLength(-1);
response.setHeader("Content-Transfer-Encoding", "binary");
response.setHeader("Content-Disposition","attachment; filename=\"" + "xxx\"");//fileName);
...
...
File f= new File(fileName);

InputStream in = new FileInputStream(f);
BufferedInputStream bin = new BufferedInputStream(in);
DataInputStream din = new DataInputStream(bin);

while(din.available() > 0){
    out.print(din.readLine());
    out.print("\n");
}
Run Code Online (Sandbox Code Playgroud)

失败的原因是servlet发送的实际标头可能与您要发送的标头不同.毕竟,如果servlet容器不知道哪些头(它出现在HTTP响应中的主体之前),那么它可以设置适当的头以确保响应有效; 因此,在写入文件之后设置标题是徒劳和冗余的,因为容器可能已经设置了标题.您可以通过使用Wireshark或HTTP调试代理(如Fiddler或WebScarab)查看网络流量来确认这一点.

您还可以参考ServletResponse.setContentType的Java EE API文档来了解此行为:

如果尚未提交响应,设置发送到客户端的响应的内容类型.给定内容类型可以包括字符编码规范,例如text/html; charset = UTF-8.如果在调用getWriter之前调用此方法,则仅根据给定的内容类型设置响应的字符编码.

可以重复调用该方法以改变内容类型和字符编码.如果在提交响应后调用此方法,则此方法无效.

...

  • 我想通知其他SO用户关于它是一个黑客以及它是如何工作的,因为这在任何地方都没有提到,这里有一个关于SO的解释:http://stackoverflow.com/questions/10615797/utility-of-http-header-内容型应用力下载换手机 (5认同)

Vla*_*hev 5

写出文件之前,设置内容类型和其他标题。对于小文件,内容被缓冲,浏览器首先获取标头。对于大数据,数据优先。