2010-02-11 51 views
2

我正在開發一個簡單的servlet,它應該通過http來提供文檔。我使用/ getDocument?fileId = 1234形式的URL。 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)

回答

5

內部小服務程序,該響應的內容類型應被設定如下:

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

ServletContext#getMimeType()查找所有<mime-mapping>條目web.xml用於與特定文件擴展名相關聯的內容類型。您可以在應用服務器自己的web.xml(例如Tomcat位於/conf/web.xml中)中找到所有默認映射。它可能缺少「新」MSOffice OpenXML文件擴展名,如xlsx,docx等。你可以將它們添加到您的web應用程序的web.xml像如下:

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

至於瀏覽器如何處理的內容類型和相關的應用程序,主要的問題就在這裏是MSIE。它會忽略Content-Disposition標頭的Content-Type標頭和filename參數。它改爲smartass-ingly根據URL中的文件擴展名猜測內容類型,並使用URL的最後一個路徑信息作爲文件名。由於您使用的請求參數如/getDocument?fileId=1234而非完整的文件名+擴展名,因此文件名將變爲getDocument,而MSIE不能可靠地「猜測」它的MIME類型。您應該在網址中包含文件名+擴展名,例如/getDocument/filename.ext。您可以通過request.getPathInfo()Servlet中獲取該部分。有關更多servlet提示,請參閱this article

至於你的Firefox沒有正確處理PDF文件的問題,這必須是Firefox中的配置錯誤。嘗試驗證一切是否正確工具>選項>應用程序。它應該以正確的方式尊重上述標題。您只應確保任何Content-Length標頭指定正確(!!),否則無法打開該文件。

+0

謝謝,那是我正在尋找的信息。 – 2010-02-11 13:34:40

+1

世界級的答案。 – 2010-02-11 15:10:20

+0

據我所知,IE *處理MIME類型。例如,請參閱http://greenbytes.de/tech/tc2231/#attwithasciifilename上的測試用例。 – 2010-02-12 12:56:54

0

我建議您檢查第二臺機器,並確保您已正確安裝Acrobat Reader(在Mozilla中,「about:plugins 「讓你進入插件註冊表)。

相關問題