周 琴
(四川省科學技術信息研究所,成都 610016)
互聯網時代,文件傳輸服務已是Web 應用系統的重要功能之一,用于完成信息的交互和共享。無論是企業的信息系統、還是電子政務系統、電子商務系統等,隨著應用規模的擴大,文件傳輸需求越來越多,要求越來越高,任務并發情況也越來越頻繁。而文件上傳/下載效率很容易受到文件大小和網絡帶寬影響,經常因為文件過大或者網絡中斷導致傳輸失敗,不得不重新傳輸。另外,文件傳輸服務作為一個常見的功能模塊,不同應用之間存在重復開發的問題,增加了系統開發成本。同時,開發者在實際開發過程中容易忽視它的重要性,導致文件傳輸的效率低下,傳輸的安全性和可靠性得不到保證。如何在高并發環境中實現大文件穩定、安全、可靠的傳輸是Web 應用系統開發需要考慮的重要問題。
針對上述問題,本文基于Hessian 協議框架研發一套通用的文件傳輸服務系統,能夠為外部網絡應用提供高性能的獨立的文件傳輸和文件加工處理服務,實現文件傳輸和加工處理與外部網絡應用相互獨立,可跨平臺用于不同網絡環境中。本文將文件分片傳輸,可解決因文件過大導致傳輸失敗的問題。通過建立統一規范的文件傳輸服務接口,供不同外部應用訪問,這樣能簡化Web 應用系統的設計并快速進行開發,同時也解決了不同應用之間重復開發相同功能模塊的問題。Web 應用系統通過訪問通用的接口與文件傳輸服務系統進行交互,告知文件傳輸服務系統將要傳輸的文件的源地址和目的地址,以及加工處理的具體任務。文件服務系統通過接口接收指令,獨立完成任務后,將文件傳輸服務狀態反饋給接口,Web 應用系統通過接口來實時查看文件傳輸服務狀態。
在OSI網絡通信模型中,RPC協議跨越了傳輸層和網絡層,使得開發高可用的分布式應用程序更加容易。近年來,基于RPC 協議的遠程服務調用在分布式項目中應用越來越廣泛,比如谷歌的gRPC、Facebook 的Thrift、阿里巴巴的Dubbo、新浪的Montan 以及Hessian、Avro、Ice等,各個框架都有其各自的優缺點。本文選取Hessian 協議作為文件傳輸系統的遠程通信架構,實現系統之間的數據傳送。它具有傳輸開銷小、網絡帶寬利用率高、數據傳遞效率高的特點,能很好地滿足文件傳輸的數據通信需求。
Hessian 是由Caucho 公司開發的一種基于二進制RPC 協議(Binary-RPC)的輕量級遠程調用框架,采用自定義描述的二進制傳輸協議,很適合發送二進制數據,利用它可以快速地開發Web 服務,不需要構建大型的框架,也不需要其它協議的支持。它的優點是能夠使得不同節點之間文件的傳輸變得非常的簡單高效,網絡應用程序只需要調用相應的接口就可以很方便地訪問Hessian 所提供的Web 服務。其處理過程可以描述為:客戶端通過Hessian 本身提供的接口來發起請求,按照Binary-RPC 協議將請求信息進行填充,填充完畢后根據自定義的序列化規則對請求信息進行序列化,將二進制格式文件轉化為流,通過Http 協議進行傳輸;服務器端在接收到流后將其返序列化出客戶端調用的方法和參數,對服務端服務進行調用,然后把處理結果返回至客戶端。Hessian 協議框架的完整調用過程如圖1所示。

圖1 Hessian協議框架
在Web 應用中,大文件上傳是一個比較重要的交互場景,如上傳較大的Word文檔、Excel表格數據、音視頻文件等。傳統的大文件上傳方式主要通過Flash 或ActiveX 來實現,常常因為文件容量過大或者網絡異常導致上傳時間較長或上傳失敗。隨著HTML 技術的發展,萬維網聯盟(W3C)在2014 年10 月推出HTML 最新標準,即HTML5。HTML5 規范提供了文件上傳、下載、讀取內容等接口對象,如FileList、File、Blob、FileReader、URL。在JavaScript 中,File對象是Blob 對象的子類,Blob 對象包含slice 方法,通過這個方法,就可以對二進制文件進行分割切片。
本文采用HTML5 規范,在客戶端使用slice方法將文件進行分割切片傳輸,服務端自動組裝合成原始文件,進而實現大容量文件傳輸功能,同時能有效提高文件上傳的效率。處理過程簡單描述為:在客戶端獲取文件的二進制內容,然后對其內容進行拆分,并將每個切片上傳到服務端,最終服務器將文件切片進行合并組裝成原始文件。在文件開始上傳之前,客戶端和服務器端需要有一次信息交互過程,主要包括文件相關信息以及約定切片的大小,當客戶端和服務器端達成共識之后就可以開始文件傳輸。
構建基于Hessian 協議框架的文件傳輸系統,需要對服務器端和客戶端分別進行開發。服務器端主要實現可供客戶端調用的接口開發、對應服務處理函數的具體實現,以及配置Servlet 發布Web 應用程序。客戶端主要創建與服務器的連接,訪問服務器端提供的接口實現文件傳輸及加工處理等功能。
服務器端主要實現將接收到的二進制流反序列化為對服務的請求,調用相應函數處理后,將處理結果序列化為二進制流返回給客戶端,不需要開發用戶界面。
3.1.1 創建Web項目
創建名為FileServer 的Web 項目作為文件傳輸的服務器端,從Hessian 官網下載最新的hessian.jar文件,存放在WEB-INF/lib 文件夾中,完成服務器端Hessian協議的安裝。
3.1.2 設計文件傳輸服務接口
創建文件上傳服務接口,命名為IFileService,實現向外界暴露服務業務,用于給客戶端調用。接口中聲明的方法包含了文件的常見操作,比如上傳、下載、重命名、復制、刪除、文件合并、添加水印等。接口代碼如下:
package fileserver.service;
import java.io.InputStream;
import java.util.Map;
public interface IFileService{
public boolean upload(String filePath,boolean isAppend,InputStream
fileContentStream);
public byte[]download(String filePath,int block-Num);
public boolean rename(String filePath,String old-FileName,String newFileName);
public boolean copyFile(String srcFilePath,String desFilePath);
public boolean delete(String filePath);
public boolean wdMergeAsDoc(String[]wdFilePaths,String pdfFilePath);
public boolean wdAddPicWaterMark(String img-Path,String destFilePath);
}
3.1.3 實現服務接口聲明的方法
具體實現服務接口中聲明的方法,完成上傳、下載及文件加工處理功能模塊的開發。以文件上傳功能為例,關鍵代碼介紹如下:
package fileserver.service.impl;
import fileserver.service.IFileService;
public class FileServiceImpl implements IFileService{
public boolean upload(String filePath,boolean isAppend,InputStream
fileContentStream){
BufferedInputStream bis=null;
BufferedOutputStream bos=null;
boolean bSuccess=false;
try{
bis = new BufferedInputStream(fileContent-Stream);
String fileFullPath = getFileFullPath(sysId,filePath);
String dirPath =fileFullPath.substring(0,file-FullPath.lastIndexO(fFile.separator));
File dirs=new File(dirPath);
i(f!dirs.exists()){
dirs.mkdirs();
}
bos=new BufferedOutputStream(new FileOutput-Stream(fileFullPath,isAppend));
byte[]buffer=new byte[1024];
int r=bis.read(buffer,0,buffer.length);
while(r >0){
bos.write(buffer,0,r);
r=bis.read(buffer,0,buffer.length);
}
}
}
3.1.4 部署服務器端的服務
基于Hessian 協議的Web 服務以Servlet 方式發布,因此需要在web.xml 文件中配置相應的HessianServlet,同時還需要配置提供給客戶端調用的接口以及URL 映射。本文將服務端應用程序部署至Tomcat,啟動服務,完成服務器端的開發和部署。
客戶端主要將遠程接口調用序列化為流,并傳輸到服務端。為了實現Hessian 服務的遠程調用,客戶端需要定義與服務器端一樣的接口類和實體類,使用Hessian 包的代理工廠類HessianProxyFactory的create方法來實現調用。
3.2.1 創建文件上傳客戶端
文件上傳客戶端界面包括操作按鈕和顯示界面。操作按鈕有“上傳”和“刪除”兩個按鈕,用于選擇需要上傳的文件或刪除已上傳的文件。顯示界面用于顯示選擇的文件名稱、文件大小、上傳進度等信息,如圖2所示。

圖2 文件上傳客戶端
3.2.2 調用遠程服務上傳文件
客戶端添加對Hessian.jar文件的引用,同時將服務器端的FileServer 接口打包成jar文件提供給客戶端調用。創建HessianProxyFactory 實例,用于獲得Hessian 服務的遠程調用,選擇需要上傳的文件,上傳至文件服務器,關鍵代碼如下所示:
public class FileClientHandler{
private IFileService fileService;
public FileClientHandler(){
ini(t);
}
public void ini(t){
HessianProxyFactory factory = new HessianProxy-Factory();
try{
String[]str=getServerPro();
fileService =(IFileService)factory.create(IFileService.class,systemId=st[r1];
}catch(MalformedURLException e){
e.printStackTrace();
}
}
本文設計并實現了與具體網絡應用相互獨立的文件傳輸服務系統,供不同的應用程序進行調用,節約了外部網絡應用的開發成本。系統基于Hessian 協議框架和HTML5 標準開發,突破了文件上傳的各種限制,能有效減少傳輸開銷、提升文件傳輸效率,保證文件傳輸的穩定性和可靠性。后續的研究工作中,還可以繼續優化和創新文件傳輸的邏輯,以提供更高效和可靠的文件傳輸服務。