1. 程式人生 > >PrimeFaces 4.0 使用 標籤實現檔案下載

PrimeFaces 4.0 使用 標籤實現檔案下載

這兩天在使用 primefaces 4.0 做壹個下載檔案的功能,去官方網站 primefaces.org 看了下,只有壹個 PDF 版使用者指南各種用例的線上 Demo ,目前可以在官方網站上找到的下載案例見於 http://www.primefaces.org/showcase/ui/fileDownload.jsf,能夠看到部分原始碼,但是找不到整個工程,實在是很不方便。後來又通過 Google 搜尋了下,終於讓我在 http://networkedblogs.com/B8rUw 找到了 primefaces-showcase 原始碼和 WAR 安裝包的下載地址,原來是在 primefaces  自己的 repository 資源庫裡的,仔細看了下,是用標籤 <p:fileDownload> 來實現的,具體的程式碼實現如下。

首先是 XHTML 頁面,包含了三部分,壹個<h:form>表單,用於提交請求到後端伺服器;壹個 <p:dialog>對話方塊,伺服器響應請求之後,但是頁面還沒有彈出檔案下載視窗這段時間裡,在頁面上顯示壹個進度條視窗;最後壹部分是 javascript 指令碼程式碼,用於控制上面的 <p:dialog>的顯示與隱藏。

01 <p:dialog modal="true" widgetVar="statusDialog" header="Status" draggable="false" closable="false" resizable="false"
>
02 <p:graphicImage value="/design/ajaxloadingbar.gif" />
03 </p:dialog>
04
05 <h:form id="form">
06 <p:commandButton id="downloadLink" value="Download" ajax="false" onclick="PrimeFaces.monitorDownload(start, stop)" icon="ui-icon-arrowthichk-s">
07 <p:fileDownload value
="#{fileDownloadController.file}" />
08 </p:commandButton>
09 </h:form>
10
11 <script type="text/javascript">
12 function start() {
13 PF('statusDialog').show();
14 }
15
16 function stop() {
17 PF('statusDialog').hide();
18 }
19 </script>

其中幾個需要注意的地方是:1、<p:graphicImage>裡的 value 屬性指向了壹個 GIF 圖片,這個圖片實際放置在 WebRoot 的根目錄下,也就是說,相對路徑實際是 /WebRoot/design/ajaxloadingbar.gif ;2、在 <p:commandButton> 裡有壹個 onclick 事件指向 PrimeFaces.monitorDownload(start, stop),其實這裡它指定了兩個方法分別是  start() 和 stop(),具體它們的表現通過 Demo  的演示效果就可以看出來。

後臺部分的程式碼主要是 FileDownloadController ,它的內容如下所示:

01 package org.primefaces.examples.view;
02
03 import java.io.InputStream;
04 import javax.faces.context.FacesContext;
05 import javax.servlet.ServletContext;
06
07 import org.primefaces.model.DefaultStreamedContent;
08 import org.primefaces.model.StreamedContent;
09
10 public class FileDownloadController {
11
12 private StreamedContent file;
13
14 public FileDownloadController() {
15 ServletContext servletContext = (ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext();
16 InputStream stream = servletContext.getResourceAsStream("/images/optimusprime.jpg");
17 file = new DefaultStreamedContent(stream, "image/jpg", "downloaded_optimus.jpg");
18 }
19
20 public StreamedContent getFile() {
21 return file;
22
23 }
上述程式碼則比較簡單,沒有什麼好說的,唯壹的地方在於 getResourceAsStream() 方法的引數是壹個檔案的相對路徑,這個路徑也是相對於 WebRoot 的,也就是說,真正的 optimusprime.jpg 圖片是放置在 WebRoot 的 /WebRoot/images/optimusprime.jpg 目錄下,這樣 Controller 才能正確讀取到這個圖片。至於 DefaultStreamedContent 這個類,則是 primefaces 框架自己提供的壹個簡單的獲取 stream 輸入流的實現類,它原本有四個構造方法(如下所示),但是我們這裡只使用了第3種。
01 1public DefaultStreamedContent(InputStream stream);
02 2public DefaultStreamedContent(InputStream stream, String contentType);
03 3public DefaultStreamedContent(InputStream stream, String contentType, String name);
04 4public DefaultStreamedContent(InputStream stream, String contentType, String name, String contentEncoding);
05
06 引數說明:
07 1、stream:要下載的檔案的輸入流物件;
08 2、contentType:要下載的檔案的檔案型別,確切的說是mimeType,如MS EXCEL2003 的mimeType 是"application/vnd.ms-excel",JPG圖片的mimeType 是“<span></span>image/jpg”;
09 3、name:給下載的檔案重新指定壹個檔名(包括副檔名),會顯示在瀏覽器端的下載視窗中;
10 4、contentEncoding:檔案的預設編碼格式,如GBK、UTF-8、GB18030等,這個欄位貌似用的稍少些;
按照這樣的方式,我們就可以成功的實現檔案下載功能了。另外,附壹張 primefaces-showcase 的 war 包解壓之後的目錄結構圖。

最後我想吐槽下,Primefaces 網站上的超連結和選單排列真有夠亂的,頂上的幾個連結我以為是帶有下拉列表的,結果點選之後是直接全頁面重新整理並跳轉的,真正的各種菜單鏈接其實是放在頁面底部的黑色背景區域裡的,花了我好長時間才找到。而且光是通過網站我們還不能直接找到 primefaces repository 的地址,只能找到它的線上 Demo,其中有很多小的細節通過 Demo 其實是看不出來的,最好的辦法是結合完整的原始碼進行學習。不知道 PrimeFaces 官方是怎麼想的,把個網站建設的亂七八糟。
本文重點參考瞭如下內容:
[1]Download PrimeFaces ShowCase and Source Code  http://networkedblogs.com/B8rUw
[2]What are the Microsoft Office MIME Types http://filext.com/faq/office_mime_types.php
[3]PrimeFaces Demo War 包下載地址(包含所有的樣例程式碼) http://repository.primefaces.org/org/primefaces/prime-showcase/1.0.0-SNAPSHOT/prime-showcase-1.0.0-SNAPSHOT.war