使用内容处置下载文件时出现问题

Posted

技术标签:

【中文标题】使用内容处置下载文件时出现问题【英文标题】:Having issue while downloading a file using content-disposition 【发布时间】:2014-11-03 17:37:22 【问题描述】:

我希望我的程序在文件开始下载之前有一个弹出另存为窗口选项,但是当我运行我的 servlet 时,它会自动开始下载文件。我在这里错过了什么?

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    ServletOutputStream outputStream = response.getOutputStream();
    FileInputStream fis=new FileInputStream("E:/sound.mp3");
    response.setContentLength(fis.available());
    response.setContentType("audio/basic");
    response.addHeader("content-disposition", "attachment;filename=abc.mp3");
    while(true)
        int read = fis.read();
        if(read==-1)break;
        outputStream.write(read);
    
    fis.close();        

【问题讨论】:

我相信这是在服务器端。您正在尝试将服务器事件传播到客户端。 看看:***.com/questions/3802510/… 和 ***.com/questions/2226192/… 问候 @DaniloMuñoz:据我所知,两种情况与我的情况不同......但感谢您的关注 @HelloWorld 提供其他信息,例如您如何访问您的 servlet 以及您在哪里运行 servlet @shekharsuman 这不是重复的选项。 【参考方案1】:

您的程序不是桌面/独立程序,因为它是在服务器上运行的 servlet。当您在 Eclipse 中通过右键单击并run as -> run on server 运行它时,Eclipse 实际上会打开一个网页来显示结果。因此,您的程序现在是一个 Web 应用程序,而 Eclipse(或它打开的页面)是 客户端。客户端正在保存您发送的信息,而不是您的程序。明白了吗?

content-disposition 标头仅用于建议下载的文件名。浏览器设置定义它是否会打开 Save As 窗口。你无法控制它。

例如,在谷歌浏览器中,Setting/Advanced Setting/Downloads 中有Ask where to save each file before downloading 选项。只有在选择此选项时,才会打开所需的对话框。否则它将保存在默认位置(也在浏览器设置中定义)。所有浏览器都有类似的选项。

还请注意,根据content-type 标头,浏览器将尝试显示 内容,而不是下载。例如,浏览器会尝试显示文本和 html。但是您可以通过将标题设置为不可显示的类型来强制下载:

response.setContentType("application/octet-stream");

如果您不想创建 Web 应用程序:由于您的程序在 服务器 上运行,它只是发送信息并完成。 客户端程序决定如何处理它。在您目前的情况下,客户端是浏览器(或 Eclipse 打开浏览器页面)。诸如content-disposition 之类的标头是针对浏览器的。如果您要创建自己的客户端(Swing 客户端、android 应用程序、iPhone 应用程序)而不是浏览器,那么客户端将从服务器接收信息并决定如何处理它(显示或保存在任何方式),甚至忽略 HTTP 标头。

【讨论】:

【参考方案2】:

试试看这里:http://www.java2s.com/Code/Java/Swing-JFC/DemonstrationofFiledialogboxes.htm

取出他们代码中的主要语句并将run(new FileChooserTest(), 250, 110); 放入您自己的代码中。如果我这样做,我将创建一个名为 saveStatus 的 int 和 3 个等于 0、1 和 2 的决赛,名为 waitingsavecancel。然后我会在你的其他编程中做一个while循环,看看saveStatus是否等于waiting来暂停你的程序(但不是对话框)。之后,我会做一个 if 语句来查看 saveStatus 是否等于 save。如果是,请下载它,如果不是,请不要。就这么简单。

【讨论】:

【参考方案3】:

您的问题是 Mime 类型。大多数浏览器会直接下载某些类型(尤其是那些已知特定处理程序的类型)。使用应用程序/二进制文件确实有点帮助,但即便如此,某些浏览器也可能被配置为下载它或解释处置处理程序中的文件扩展名。

我认为大多数解决方案在下载链接之前的页面上使用 javascript

【讨论】:

【参考方案4】:

您必须手动实现对话框,例如(http://docs.oracle.com/javase/7/docs/api/javax/swing/JFileChooser.html)。用户选择文件后,您将能够开始 http 请求下载(到您的 servlet)并将文件保存到所需的路径。

【讨论】:

以上是关于使用内容处置下载文件时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 QNetworkAccessManager::get() 函数从 FTP 下载文件时出现问题

尝试从数据库下载“图像”列内容时出现日期类型转换错误

尝试使用 Retrofit @Streaming 注释下载大文件时出现 OutOfMemoryError

使用 .NET SDK 从 Azure 文件共享下载空文件时出现 InvalidRange 错误

从 Azure Blob 存储文件名下载文件时出现的问题包含哈希 (#)

解析软件包时出现问题应该怎么处理?