如何指定文档的响应内容类型以便跨浏览器一致地工作?

时间:2010-02-11 12:42:40

标签: http servlets mime-types

我正在开发一个应该通过http提供文档的简单servlet。我使用/ getDocument形式的URL?fileId = 1234。 servlet只是1)设置response.contentType和2)写入response.outputStream。

问题在于正确设置内容类型以使浏览器理解响应(即,使用正确的应用程序显示文档)。具体做法是:

a)对于PDF文件,如果我将内容类型设置为“application / pdf”,则Internet Explorer会理解(立即显示文档)但Firefox不会(显示空白页面而不尝试打开任何pdf查看器插件)。如果我将其设置为“application / x-octetstream”,Firefox会理解它(正确显示),但是当它要求我保存或打开它时,Internet Explorer会说“未知文件类型”。

b)Firefox了解“application / msword”和“application / vnd.ms-excel”,但是,奇怪的是,Internet Explorer没有,简单地说“未知文件类型”。

是否有可能在所有浏览器中始终如一地工作,如果是这样,为各种文档类型设置内容类型的正确方法是什么?是否还有其他在响应中设置以便正常工作?或者,正如我怀疑的那样,当URL没有以相应的文件扩展名结束时,浏览器是否会感到困惑? (即,getFile?fileId = 1234而不是例如getFile / test.pdf)

2 个答案:

答案 0 :(得分:5)

在servlet中,响应内容类型应该设置如下:

response.setContentType(getServletContext().getMimeType(filenameWithExtension));

ServletContext#getMimeType()查找<mime-mapping>中与某些文件扩展名关联的内容类型的所有web.xml条目。您可以在appserver自己的web.xml中找到所有默认映射(例如,如果Tomcat位于/conf/web.xml中)。它可能缺少像xlsxdocx这样的“新”MSOffice OpenXML文件扩展名。您可以将它们添加到您的webapp web.xml,如下所示:

<mime-mapping>
    <extension>xlsx</extension>
    <mime-type>application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</mime-type>
</mime-mapping>

关于浏览器如何处理内容类型和相关应用程序,这里的主要问题是MSIE。它忽略Content-Type标头和filename标头的Content-Disposition参数。它改为 smartass-ingly 根据URL中的文件扩展名猜测内容类型,并使用URL的最后一个pathinfo作为文件名。由于您使用了/getDocument?fileId=1234之类的请求参数而不是完整的文件名+扩展名,因此文件名将变为getDocument,并且MSIE无法可靠地“猜测”它的mime类型。您应该在网址中加入文件名+扩展名,例如/getDocument/filename.ext。您可以通过Servletrequest.getPathInfo()中抓取该部分。有关更多servlet提示,请参阅this article

关于Firefox无法正确处理PDF文件的问题,这必须是Firefox中的错误配置。尝试在工具&gt;中验证所有内容是否正确选项&gt; 应用。即,应该以正确的方式尊重上述标题。您应该只确保指定了任何Content-Length标头(!!),否则无法打开文件。

答案 1 :(得分:0)

我建议你检查第二台机器,并确保你已经正确安装了Acrobat Reader(在Mozilla中,“about:plugins”可以让你进入插件注册表)。