熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

Apache FileUpload文件上傳組件API解析

2013-11-23 19:06:22  來源: Java核心技術 

  Java Web開發人員可以使用Apache文件上傳組件來接收浏覽器上傳的文件該組件由多個類共同組成但是對於使用該組件來編寫文件上傳功能的Java Web開發人員來說只需要了解和使用其中的三個類DiskFileUploadFileItem和FileUploadException這三個類全部位於monsfileupload包中

   DiskFileUpload類

  DiskFileUpload類是Apache文件上傳組件的核心類應用程序開發人員通過這個類來與Apache文件上傳組件進行交互但現在Apache建議使用ServletFileUpload類兩個類的方法類似下面介紹DiskFileUpload類中的幾個常用的重要方法

  .setSizeMax方法

  setSizeMax方法用於設置請求消息實體內容的最大允許大小以防止客戶端故意通過上傳特大的文件來塞滿服務器端的存儲空間單位為字節其完整語法定義如下

  public void setSizeMax(long sizeMax)

  如果請求消息中的實體內容的大小超過了setSizeMax方法的設置值該方法將會拋出FileUploadException異常

  .setSizeThreshold方法

  Apache文件上傳組件在解析和處理上傳數據中的每個字段內容時需要臨時保存解析出的數據因為Java虛擬機默認可以使用的內存空間是有限的(筆者測試不大於M)超出限制時將會發生javalangOutOfMemoryError錯誤如果上傳的文件很大例如上傳M的文件在內存中將無法保存該文件內容Apache文件上傳組件將用臨時文件來保存這些數據但如果上傳的文件很小例如上傳個字節的文件顯然將其直接保存在內存中更加有效setSizeThreshold方法用於設置是否使用臨時文件保存解析出的數據的那個臨界值該方法傳入的參數的單位是字節其完整語法定義如下

  public void setSizeThreshold(int sizeThreshold)

   setRepositoryPath方法

  setRepositoryPath方法用於設置setSizeThreshold方法中提到的臨時文件的存放目錄這裡要求使用絕對路徑其完整語法定義如下

  public void setRepositoryPath(String repositoryPath)

  如果不設置存放路徑那麼臨時文件將被儲存在javaiotmpdir這個JVM環境屬性所指定的目錄中tomcat 將這個屬性設置為了<tomcat安裝目錄>/temp/目錄

   parseRequest方法

  parseRequest 方法是DiskFileUpload類的重要方法它是對HTTP請求消息進行解析的入口方法如果請求消息中的實體內容的類型不是multipart/formdata該方法將拋出FileUploadException異常parseRequest 方法解析出FORM表單中的每個字段的數據並將它們分別包裝成獨立的FileItem對象然後將這些FileItem對象加入進一個List類型的集合對象中返回parseRequest 方法的完整語法定義如下

  public List parseRequest(HttpServletRequest req)

  parseRequest 方法還有一個重載方法該方法集中處理上述所有方法的功能其完整語法定義如下

  parseRequest(HttpServletRequest reqint sizeThresholdlong sizeMax

  String path)

  這兩個parseRequest方法都會拋出FileUploadException異常

   isMultipartContent方法

  isMultipartContent方法方法用於判斷請求消息中的內容是否是multipart/formdata類型是則返回true否則返回falseisMultipartContent方法是一個靜態方法不用創建DiskFileUpload類的實例對象即可被調用其完整語法定義如下

  public static final boolean isMultipartContent(HttpServletRequest req)

   setHeaderEncoding方法

  由於浏覽器在提交FORM表單時會將普通表單中填寫的文本內容傳遞給服務器對於文件上傳字段除了傳遞原始的文件內容外還要傳遞其文件路徑名等信息如後面的圖所示不管FORM表單采用的是application/xwwwformurlencoded編碼還是multipart/formdata編碼它們僅僅是將各個FORM表單字段元素內容組織到一起的一種格式而這些內容又是由某種字符集編碼來表示的關於浏覽器采用何種字符集來編碼FORM表單字段中的內容請參看筆者編著的《深入體驗java Web開發內幕——核心基礎》一書中的第的講解multipart/formdata類型的表單為表單字段內容選擇字符集編碼的原理和方式與application/xwwwformurlencoded類型的表單是相同的FORM表單中填寫的文本內容和文件上傳字段中的文件路徑名在內存中就是它們的某種字符集編碼的字節數組形式Apache文件上傳組件在讀取這些內容時必須知道它們所采用的字符集編碼才能將它們轉換成正確的字符文本返回

  對於浏覽器上傳給WEB服務器的各個表單字段的描述頭內容Apache文件上傳組件都需要將它們轉換成字符串形式返回setHeaderEncoding 方法用於設置轉換時所使用的字符集編碼其原理與筆者編著的《深入體驗java Web開發內幕——核心基礎》一書中的第節講解的ServletRequestsetCharacterEncoding方法相同setHeaderEncoding 方法的完整語法定義如下

  public void setHeaderEncoding(String encoding)

  其中encoding參數用於指定將各個表單字段的描述頭內容轉換成字符串時所使用的字符集編碼

  注意如果讀者在使用Apache文件上傳組件時遇到了中文字符的亂碼問題一般都是沒有正確調用setHeaderEncoding方法的原因

    FileItem類

  FileItem類用來封裝單個表單字段元素的數據一個表單字段元素對應一個FileItem對象通過調用FileItem對象的方法可以獲得相關表單字段元素的數據FileItem是一個接口在應用程序中使用的實際上是該接口一個實現類該實現類的名稱並不重要程序可以采用FileItem接口類型來對它進行引用和訪問為了便於講解這裡將FileItem實現類稱之為FileItem類FileItem類還實現了Serializable接口以支持序列化操作

  對於multipart/formdata類型的FORM表單浏覽器上傳的實體內容中的每個表單字段元素的數據之間用字段分隔界線進行分割兩個分隔界線間的內容稱為一個分區每個分區中的內容可以被看作兩部分一部分是對表單字段元素進行描述的描述頭另外一部是表單字段元素的主體內容如圖所示

  圖

  主體部分有兩種可能性要麼是用戶填寫的表單內容要麼是文件內容FileItem類對象實際上就是對圖中的一個分區的數據進行封裝的對象它內部用了兩個成員變量來分別存儲描述頭和主體內容其中保存主體內容的變量是一個輸出流類型的對象當主體內容的大小小於DiskFileUploadsetSizeThreshold方法設置的臨界值大小時這個流對象關聯到一片內存主體內容將會被保存在內存中當主體內容的數據超過DiskFileUploadsetSizeThreshold方法設置的臨界值大小時這個流對象關聯到硬盤上的一個臨時文件主體內容將被保存到該臨時文件中臨時文件的存儲目錄由DiskFileUploadsetRepositoryPath方法設置臨時文件名的格式為upload_(八位或八位以上的數字)tmp這種形式FileItem類內部提供了維護臨時文件名中的數值不重復的機制以保證了臨時文件名的唯一性當應用程序將主體內容保存到一個指定的文件中時或者在FileItem對象被垃圾回收器回收時或者Java虛擬機結束時Apache文件上傳組件都會嘗試刪除臨時文件以盡量保證臨時文件能被及時清除

  下面介紹FileItem類中的幾個常用的方法

   isFormField方法

  isFormField方法用於判斷FileItem類對象封裝的數據是否屬於一個普通表單字段還是屬於一個文件表單字段如果是普通表單字段則返回true否則返回false該方法的完整語法定義如下

  public boolean isFormField()

   getName方法

  getName方法用於獲得文件上傳字段中的文件名對於圖中的第三個分區所示的描述頭getName方法返回的結果為字符串C:\bggif如果FileItem類對象對應的是普通表單字段getName方法將返回null即使用戶沒有通過網頁表單中的文件字段傳遞任何文件但只要設置了文件表單字段的name屬性浏覽器也會將文件字段的信息傳遞給服務器只是文件名和文件內容部分都為空但這個表單字段仍然對應一個FileItem對象此時getName方法返回結果為空字符串讀者在調用Apache文件上傳組件時要注意考慮這個情況getName方法的完整語法定義如下

  public String getName()

  注意如果用戶使用Windows系統上傳文件浏覽器將傳遞該文件的完整路徑如果用戶使用Linux或者Unix系統上傳文件浏覽器將只傳遞該文件的名稱部分

  .getFieldName方法

  getFieldName方法用於返回表單字段元素的name屬性值也就是返回圖中的各個描述頭部分中的name屬性值例如name=p中的pgetFieldName方法的完整語法定義如下

  public String getFieldName()

   write方法

  write方法用於將FileItem對象中保存的主體內容保存到某個指定的文件中如果FileItem對象中的主體內容是保存在某個臨時文件中該方法順利完成後臨時文件有可能會被清除該方法也可將普通表單字段內容寫入到一個文件中但它主要用途是將上傳的文件內容保存在本地文件系統中其完整語法定義如下

  public void write(File file)

  .getString方法

  getString方法用於將FileItem對象中保存的主體內容作為一個字符串返回它有兩個重載的定義形式

  public javalangString getString()

  public javalangString getString(javalangString encoding)

  throws javaioUnsupportedEncodingException

  前者使用缺省的字符集編碼將主體內容轉換成字符串後者使用參數指定的字符集編碼將主體內容轉換成字符串如果在讀取普通表單字段元素的內容時出現了中文亂碼現象請調用第二個getString方法並為之傳遞正確的字符集編碼名稱

   getContentType方法

  getContentType 方法用於獲得上傳文件的類型對於圖中的第三個分區所示的描述頭getContentType方法返回的結果為字符串image/gifContentType字段的值部分如果FileItem類對象對應的是普通表單字段該方法將返回nullgetContentType 方法的完整語法定義如下

  public String getContentType()

   isInMemory方法

  isInMemory方法用來判斷FileItem類對象封裝的主體內容是存儲在內存中還是存儲在臨時文件中如果存儲在內存中則返回true否則返回false其完整語法定義如下

  public boolean isInMemory()

   delete方法

  delete方法用來清空FileItem類對象中存放的主體內容如果主體內容被保存在臨時文件中delete方法將刪除該臨時文件盡管Apache組件使用了多種方式來盡量及時清理臨時文件但系統出現異常時仍有可能造成有的臨時文件被永久保存在了硬盤中在有些情況下可以調用這個方法來及時刪除臨時文件其完整語法定義如下

  public void delete()

   FileUploadException類

  在文件上傳過程中可能發生各種各樣的異常例如網絡中斷數據丟失等等為了對不同異常進行合適的處理Apache文件上傳組件還開發了四個異常類其中FileUploadException是其他異常類的父類其他幾個類只是被間接調用的底層類對於Apache組件調用人員來說只需對FileUploadException異常類進行捕獲和處理即可

   ServletRequestContext

  ServletRequestContext類提供訪問request的方法實現RequestContext接口


From:http://tw.wingwit.com/Article/program/Java/hx/201311/26285.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.