2011-09-28 59 views
1

我有一個JSF頁面,它使用支持bean將PDF文檔傳輸到瀏覽器。這個功能很好用,而且在iOS設備上測試這個功能之前,我還沒有遇到任何問題。JSF在iOS設備上流式傳輸PDF

在iPad和iPod Touch上的Safari上,PDF流最終只會在獲取響應時粘貼爲網頁上的不可滾動圖層。在桌面上的瀏覽器中,文件會提示保存或打開並使用Adobe Reader正確打開。這是一個問題,因爲只有部分PDF的第一頁顯示在iOS設備上,並且無法查看其他部分。

我已經在網絡上測試過這些設備上的其他PDF,它們的行爲不一樣。啓動PDF應用程序或Safari加載可滾動的預覽,這是預期的結果。有沒有其他人有這個?

我的支持bean正在將PDF的緩衝輸入流寫入輸出流。我已經設置了以下響應標頭:

response.setContentType ("application/pdf"); 
response.setContentLength(inputLength); 
response.setHeader ("Content-Disposition", "inline;filename=\"" + saveFilename + ".pdf\""); 
response.setHeader ("Cache-Control", "must-revalidate, post-check=0, pre-check=0, public"); 

我試圖將內容處置從內聯切換爲附件,但這並沒有幫助。

回答

0

我想象那些設備需要在服務器端支持Range,以便內容可以分開請求。這最終最終節省了不必要的網絡帶寬,並提高了客戶端的性能感受。

如果這些PDF是動態生成的,那麼最好的辦法是將它們寫入磁盤文件系統中的一個臨時位置,並將請求重定向到一個通過servlet讀取它們的URL。擁有物理文件是強制性的,因爲您想使用RandomAccessFile以便能夠返回文件的部分內容。該課程需要磁盤上的物理File

這裏是它使用File#createTempFile()創建一個臨時文件和重定向的文件名作爲URL參數響應servlet的一個例子:

File tempFile = File.createTempFile(saveFilename, ".pdf"); 
OutputStream output = new FileOutputStream(tempFile); 
// Now write PDF to output. 
// ... 

// Then, redirect to some servlet URL. 
String tempFilename = tempFile.getName(); 
externalContext.redirect("/pdf/" + URLEncoder.encode(tempFilename, "UTF-8")); 

然後,你需要有一個servlet像this one支持範圍請求。您只需修改它即可將basePath的值更改爲System.getProperty("java.io.tmpdir")。最後,將這個servlet映射到/pdf/*的URL模式。

或者,如果您對服務器有完全的管理控制權,那麼您還可以創建指向服務器磁盤文件系統某處絕對路徑的附加web應用程序上下文。例如。 /var/webapp/pdf。在例如Tomcat的情況下,可以通過添加以下到/conf/server.xml使這個公開:

<Context docBase="/var/webapp/pdf" path="/pdf" /> 

這樣,/var/webapp/pdf文件夾的內容,請通過http://localhost:8080/context/pdf

有了上面的代碼示例中一個小的改動,以指定臨時文件的位置,

File tempFile = File.createTempFile(saveFilename, ".pdf", "/var/webapp/pdf"); 
// ... 

你並不需要一個特定的servlet了。然後,Tomcat的DefaultServlet將執行正確處理Range請求的工作。

最後但並非最不重要的一點,考慮將臨時文件存儲在會話中並實施HttpSessionListenerHttpSessionAttributeListener,該會話在會話過期時刪除臨時文件。

+0

謝謝你的文章BalusC。我嘗試了將文件保存到臨時位置並使用servlet示例的方法,創建了映射到/ pdf /的servlet並再次嘗試請求。在桌面瀏覽器上,按照我的預期進行處理,提示打開或保存。在iOS上的Safari上,它的表現與以前一樣,即使使用response.redirect,也可以將PDF分層到現有網頁上。我開始認爲這是JSF和Safari的一個錯誤,但我不確定。這些是機密文件,所以我不能直接提供這些文件的URL。 – dlau

+0

有趣。如何將靜態示例PDF放入公共webcontent並直接引用它以使'DefaultServlet'完成其工作? – BalusC

+0

是的,比它工作得很好。 iOS設備打開它並認爲它是Microsoft Word文檔。 – dlau

相關問題