我正在开发一个应该通过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)
答案 0 :(得分:5)
在servlet中,响应内容类型应该设置如下:
response.setContentType(getServletContext().getMimeType(filenameWithExtension));
ServletContext#getMimeType()
查找<mime-mapping>
中与某些文件扩展名关联的内容类型的所有web.xml
条目。您可以在appserver自己的web.xml
中找到所有默认映射(例如,如果Tomcat位于/conf/web.xml
中)。它可能缺少像xlsx
,docx
这样的“新”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
。您可以通过Servlet
在request.getPathInfo()
中抓取该部分。有关更多servlet提示,请参阅this article。
关于Firefox无法正确处理PDF文件的问题,这必须是Firefox中的错误配置。尝试在工具&gt;中验证所有内容是否正确选项&gt; 应用。即,应该以正确的方式尊重上述标题。您应该只确保指定了任何Content-Length
标头(!!),否则无法打开文件。
答案 1 :(得分:0)
我建议你检查第二台机器,并确保你已经正确安装了Acrobat Reader(在Mozilla中,“about:plugins”可以让你进入插件注册表)。