程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> JSP編程 >> 關於JSP >> 利用DWR開發基於Ajax的文件上載portlet

利用DWR開發基於Ajax的文件上載portlet

編輯:關於JSP

簡介

Web 門戶為用戶提供了訪問各種資源和服務的中心網關。與此同時,它們還為用戶提供了與其他用戶進行資源共享的平台。從照片到音頻、視頻文件再到研究用的科學數據集,用戶可以共享任何內容。因此,文件上載是 Web 門戶的一種基本的必備功能。


當今的 Web 門戶在很大程度上依賴於 Java portlet 技術。雖然很多使用 Ajax 的開發人員都給出了各種各樣的文件上載進度條解決方案,但我們還沒有聽說過哪個是基於 portlet 的。本文展示了如何開發基於 Ajax 的文件上載 portlet,此 portlet 能顯示文件上載過程的進度條。此 portlet 對於那些想要共享大型音頻、視頻和科學文件的人士尤其有用。


要跟上本文的進度,您應該對使用 Java Servlets 和 JavaServer Pages (JSPs) 進行 Web 開發十分熟悉。而且,還必須了解門戶和 portlet 技術的開發。當然,如果您對 portlet 技術還不怎麼精通,也不要現在就放棄本文,因為您會在本文中看到對 portlet 技術的簡單介紹,以及一些有用的資源可用來幫助您加快學習的進程。


在測試本文給出的這個文件上載 portlet 前,可以考慮嘗試使用一種遵從 JSR 168 規范的門戶框架,比如 IBM® WebSphere® Portal Server、Apache Pluto、eXo 平台或 Liferay Portal。我們在本文中使用的是 Apache Pluto 1.0.1、JDK 5.0 Update 10 和 Apache Ant Version 1.6.5。


portlet 的基本概念


一般地,可以將 portlet 視為一種 Web 組件。Portlet 與 servlet 類似,但前者更關注於應用程序的表示層。portlet 的典型輸出是 HTML 片斷,這些片斷可由 Web 門戶隨後再組裝起來。Portlet 本身由 portlet 容器管理。portlet 的主要特性包括:


多模式:portlet 可以在不同的模式下有不同的視圖。例如,除了查看 模式,portlet 還支持編輯 模式以便用戶可以設置其自身的首選項。

多個窗口狀態:portlet 可以最小化、最大化等。

可定制參數:portlet 可以定義參數,而這些參數可以由用戶定制。

要獲得有關 portlet 的更多詳細信息,可以參考 Java Portlet Specification 1.0,JSR 168(JSR 168 的後續版本 JSR 286 預計會於 2007 年後半年發布,其中包含了一些改進,比如 portlet 間通信和 portlet 過濾器)。相關鏈接,請參看 參考資料。


開始創建文件上載 portlet


文件上載 portlet 的基石是 Apache Commons FileUpload 包(本文也稱之為 FileUpload)。除了支持 servlet 內的文件上載外,Apache Commons FileUpload Version 1.1 包還支持 portlet 中的文件上載。本文使用的是 Apache Commons FileUpload 版本 1.2。


基本上,開發文件上載進度條需要兩步:


在服務器端檢索文件上載過程

從門戶服務器進行客戶端的文件上載檢索和顯示


文件上載過程的服務器端檢索


FileUpload 包支持使用偵聽器檢索文件上載過程。在文件上載 portlet 的 doUpload() 方法(稱為 uk.ac.dl.esc.gtg.myportlets.fileupload.FileUploadPortlet,包括在本文 下載 部分所提供的源文件中),通過調用 setProgressListener() 方法為 PortletFileUpload 設置過程偵聽器,如 清單 1 所示:

 

清單 1. 為文件上載包設置過程偵聽器


DiskFileItemFactory factory = new DiskFileItemFactory();
PortletFileUpload pfu = new PortletFileUpload(factory);
pfu.setSizeMax(uploadMaxSize); // Maximum upload size
pfu.setProgressListener(new FileUploadProgressListener());
 


偵聽器 FileUploadProgressListener(參見 清單 2)可實現 org.apache.commons.fileupload.ProgressListener 接口。update() 方法自動由 FileUpload 包調用以刷新有關所傳輸字節數的最新信息。在本文的實現中,每傳輸 10KB 數據則更新一次進度。這有助於防止更新進行得太頻繁。 getFileUploadStatus() 方法用來計算當前文件上載進度,可由客戶機通過 DWR 調用(在下一節討論)。


清單 2. 檢索文件上載過程的文件上載偵聽器

 

package uk.ac.dl.esc.gtg.myportlets.fileupload;

import java.text.NumberFormat;

import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class FileUploadProgressListener implements ProgressListener {
private static Log log = LogFactory.getLog(FileUploadProgressListener.class);

private static long bytesTransferred = 0;

private static long fileSize = -100;

private long tenKBRead = -1;

public FileUploadProgressListener() {
}

public String getFileUploadStatus() {
// per looks like 0% - 100%, remove % before submission
String per = NumberFormat.getPercentInstance().format(
(double) bytesTransferred / (double) fileSize);
return per.substring(0, per.length() - 1);
}

public void update(long bytesRead, long contentLength, int items) {
// update bytesTransferred and fileSize (if required) every 10 KB is
// read
long tenKB = bytesRead / 10240;
if (tenKBRead == tenKB)
return;
tenKBRead = tenKB;

bytesTransferred = bytesRead;
if (fileSize != contentLength)
fileSize = contentLength;
}

}
 


文件上載過程的客戶端檢索


服務器和客戶間就文件上載過程的通信是通過使用 Ajax 實現的。我們選用 Direct Web Remoting (DWR) 來提供 portlet 中的 Ajax 支持。DWR 是一種面向 Java 開發人員的理想框架,可用來將 Ajax 引入 Web 開發過程中,原因是它可以讓浏覽器中的 JavaScript 與服務器端的 Java 對象互動。要在 portlet 中使用 DWR,必須執行以下步驟 (更多有關如何配置 DWR 的信息,請參看 參考資料):


Direct Web Remoting 的妙處就在於此:客戶機可以和服務器端的 Java 對象交互。


通過 WEB-INF/web.xml 配置 DwrServlet(參見 清單 3)。

在 WEB-INF/dwr.xml 內定義一個或更多的客戶機可與之通信的服務器端對象。在 清單 4 中,FileUploadProgressListener 針對 DWR 定義以便客戶機可以調用這個自動生成的 JavaScript。此外,只有 getFileUploadStatus 方法可以被客戶機調用,另一個公共方法 update 則不允許被訪問(請參看 清單 2)。

將與 DWR 有關的 JavaScript 代碼包括在 fileupload-view.jsp(參看 清單 5)。

將 DWR 庫包括在 portlet 應用程序。


清單 3. 在 WEB-INF/web.xml 中配置 DwrServlet

 

<!-- DWR servlet -->
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<display-name>DWR Servlet</display-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>false</param-value>
</init-param>
</servlet>

<!-- DWR servlet mapping -->
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-patter>
</servlet-mappin>
 


清單 4. WEB-INF/dwr.xml

 

<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"
"http://getahead.org/dwr//dwr20.dtd">

<dwr>
<allow>
<create creator="new" javascript="FileUploadProgressListener">
<param name="class"
value="uk.ac.dl.esc.gtg.myportlets.fileupload.FileUploadProgressListener"/>
<include method="getFileUploadStatus"/>
</create>
</allow>
</dwr>
 


清單 5 所示的 JSP 文件 fileupload-view.jsp 展示了 DWR 如何有助於從服務器端檢索文件上載過程。一旦選中了文件並單擊了 Upload 按鈕(參看 圖 1),fileupload_ajax_query_upload_status() 方法會被即刻調用。此方法之後會以異步模式調用 FileUploadProgressListener 的 getFileUploadStatus() 方法(參見 清單 2)。DWR 的妙處就在於此:客戶機可以和服務器端的 Java 對象交互。一旦收到響應,fileupload_ajax_show_upload_status() 方法會被調用以刷新此過程。如果文件上載沒有完成,更新後的過程就會在兩秒種之後檢索。


清單 5. 文件上載 portlet JSP 文件 —— fileupload-view.jsp

 

<%@ page session="false" %>
<%@ page contentType="text/html" %>
<%@ page import="javax.portlet.PortletURL" %>
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
<portlet:defineObjects/>

<script type="text/javascript"
src=<%= renderResponse.encodeURL(renderRequest.getContextPath()
+ "/dwr/interface/FileUploadProgressListener.js") %>>
</sc

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved