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

Knu*_*daa 2 servlets http mime-types

我正在开发一个简单的servlet,它应该通过http提供文档.我使用/ 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)

Bal*_*usC 5

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

response.setContentType(getServletContext().getMimeType(filenameWithExtension));
Run Code Online (Sandbox Code Playgroud)

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

<mime-mapping>
    <extension>xlsx</extension>
    <mime-type>application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</mime-type>
</mime-mapping>
Run Code Online (Sandbox Code Playgroud)

至于浏览器如何处理内容类型和相关应用程序,这里的主要问题是MSIE.它忽略Content-Type标题和标题的filename参数Content-Disposition.它反而智能地根据URL中的文件扩展名猜测内容类型,并使用URL的最后一个pathinfo作为文件名.由于您使用了一个请求参数,/getDocument?fileId=1234而不是一个完整的文件名+扩展名,文件名将变为,getDocument并且MSIE无法可靠地"猜测"它的mime类型.你应该在URL中包含文件名+扩展名/getDocument/filename.ext.你可以抓住的那部分Servlet通过request.getPathInfo().有关更多servlet提示,请参阅此文章.

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