與文件上傳到的三個類:FileItem類、ServletFileUpload 類、DiskFileItemFactory類

文件上傳:html

ServletFileUpload負責處理上傳的文件數據,並將表單中每一個輸入項封裝成一個FileItem對象中, 在使用ServletFileUpload對象解析請求時須要根據DiskFileItemFactory對象的屬性sizeThreshold(臨界值)和repository(臨時目錄)來決定將解析獲得的數據保存在內存仍是臨時文件中,若是是臨時文件,保存在哪一個臨時目錄中?。因此,咱們須要在進行解析工做前構造好DiskFileItemFactory對象,經過ServletFileUpload對象的構造方法或setFileItemFactory()方法設置ServletFileUpload對象的fileItemFactory屬性。java

簡單點就是:ServletFileUpload和DiskFileItemFactory是成對出現的,ServletFileUpload負責解析請求,而解析後的對象存放位置(內存仍是臨時文件形式)是經過,setFileItemFactory屬性或者是構造函數來設定數據庫

FileItem類apache

在HTML頁面input  必須有 name  <input type="file" name="filename">數組

表單若是包含一個文件上傳輸入項的話,這個表單的enctype屬性就必須設置爲multipart/form-data瀏覽器

<form action ="/day16/servlet/UpLoadServlet" enctype="multipart/form-data" method="post">tomcat

瀏覽器表單的類型若是爲multipart/form-data,那麼瀏覽器在提交表單數據時,它將採用MIME協議對數據進行封裝後提交,在服務器這端也將不能採用服務器

原來傳統的方工獲取數據了。在服務器端想獲取數據就要經過流。request提供了一個getInputStream讀取流。函數

FileItem類的經常使用方法:post

1.  boolean isFormField()

        isFormField方法用於判斷FileItem類對象封裝的數據是一個普通文本表單字段,仍是一個文件表單字段,若是是普通表單字段則返回true,不然返回false。所以,可使用該方法判斷是否爲普通表單域,仍是文件上傳表單域

2.  String getName()
       getName方法用於得到文件上傳字段中的文件名。

       注意IE或FireFox中獲取的文件名是不同的,IE中是絕對路徑,FireFox中只是文件名。

3.  String getFieldName()
      getFieldName方法用於返回表單標籤name屬性的值。如上例中<input type="text" name="column" />的value。

4.  void write(File file)

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

5.  String getString()
      getString方法用於將FileItem對象中保存的數據流內容以一個字符串返回,它有兩個重載的定義形式:

      public Java.lang.String getString()

      public java.lang.String getString(java.lang.String encoding)

             throws java.io.UnsupportedEncodingException

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

6.  String getContentType()
        getContentType 方法用於得到上傳文件的類型,即表單字段元素描述頭屬性「Content-Type」的值,如「image/jpeg」。若是FileItem類對象對應的是普通表單字段,該方法將返回null。

7.  boolean isInMemory()
        isInMemory方法用來判斷FileItem對象封裝的數據內容是存儲在內存中,仍是存儲在臨時文件中,若是存儲在內存中則返回true,不然返回false。

8.  void delete()
       delete方法用來清空FileItem類對象中存放的主體內容,若是主體內容被保存在臨時文件中,delete方法將刪除該臨時文件。

        儘管當FileItem對象被垃圾收集器收集時會自動清除臨時文件,但及時調用delete方法能夠更早的清除臨時文件,釋放系統存儲資源。另外,當系統出現異常時,仍有可能形成有的臨時文件被永久保存在了硬盤中。

9.  InputStream getInputStream()
    以流的形式返回上傳文件的數據內容。

10. long getSize()
      返回該上傳文件的大小(以字節爲單位)。


爲了方便用戶處理文件上傳數據,Apache開源組織提供了一個用來處理表單文件上傳的一個開源組件(Commons-fileupload).使用Commons-fileupload組件實現文件上傳,須要導入該組件相應的jar包.

Commons-fileupload和commons-io兩個jar包.

DiskFileItemFactory是建立FileItem對象的工廠包括方法:

1.public void setSizeThreshold(int?sizeThreshold) 
設置內存緩衝區的大小,默認值爲10K,若是文件大於10K,將使用臨時文件緩

存上傳文件.

2.public void setRepository(Java.io.File repository)
指定臨時文件目錄

3.public DiskFileItemFactory();

 

 

ServletFileUpload 類

ServletFileUpload負責處理上傳的文件數據,並將表單中每一個輸入項封裝成一個FileItem對象中.

org.apache.commons.fileupload.servlet.ServletFileUpload類是Apache文件上傳組件處理文件上傳的核心高級類(所謂高級就是不須要管底層實現,暴露給用戶的簡單易用的接口)。

使用其parseRequest(HttpServletRequest) 方法能夠將經過表單中每個HTML標籤提交的數據封裝成一個FileItem對象,而後以List列表的形式返回。使用該方法處理上傳文件簡單易用。

 若是你但願進一步提升新能,你能夠採用 getItemIterator 方法,直接得到每個文件項的數據輸入流,對數據作直接處理。

 在使用ServletFileUpload對象解析請求時須要根據DiskFileItemFactory對象的屬性sizeThreshold(臨界值)和repository(臨時目錄)來決定將解析獲得的數據保存在內存仍是臨時文件中,若是是臨時文件,保存      在哪一個臨時目錄中?。因此,咱們須要在進行解析工做前構造好DiskFileItemFactory對象,經過ServletFileUpload對象的構造方法或setFileItemFactory()方法設置ServletFileUpload對象的fileItemFactory屬性。

 

ServletFileUpload類經常使用方法:
1)  public void setSizeMax(long sizeMax)
        setSizeMax方法繼承自FileUploadBase類,用於設置請求消息實體內容(即全部上傳數據)的最大尺寸限制,以防止客戶端惡意上傳超大文件來浪費服務器端的存儲空間。其參數是以字節爲單位的long型數字。

       在請求解析的過程當中,若是請求消息體內容的大小超過了setSizeMax方法的設置值,將會拋出FileUploadBase內部定義的SizeLimitExceededException異常(FileUploadException的子類)。該方法有一個對應的讀方法:public long getSizeMax()方法。

2) public void setFileSizeMax(long fileSizeMax)
        setFileSizeMax方法繼承自FileUploadBase類,用於設置單個上傳文件的最大尺寸限制,以防止客戶端惡意上傳超大文件來浪費服務器端的存儲空間。其參數是以字節爲單位的long型數字。該方法有一個對應的讀方法:public long geFileSizeMax()方法。

       在請求解析的過程當中,若是單個上傳文件的大小超過了setFileSizeMax方法的設置值,將會拋出FileUploadBase內部定義的FileSizeLimitExceededException異常(FileUploadException的子類)。

3) public List parseRequest(javax.servlet.http.HttpServletRequest req)
        parseRequest 方法是ServletFileUpload類的重要方法,它是對HTTP請求消息體內容進行解析的入口方法。它解析出FORM表單中的每一個字段的數據,並將它們分別包裝成獨立的FileItem對象,而後將這些FileItem對象加入進一個List類型的集合對象中返回。

       該方法拋出FileUploadException異常來處理諸如文件尺寸過大、請求消息中的實體內容的類型不是「multipart/form-data」、IO異常、請求消息體長度信息丟失等各類異常。每一種異常都是FileUploadException的一個子類型。

4)  public FileItemIterator getItemIterator(HttpServletRequest request)
        getItemIterator方法和parseRequest 方法基本相同。可是getItemIterator方法返回的是一個迭代器,該迭代器中保存的不是FileItem對象,而是FileItemStream 對象,若是你但願進一步提升新能,你能夠採用getItemIterator方法,直接得到每個文件項的數據輸入流,作底層處理;若是性能不是問題,你但願代碼簡單,則採用parseRequest方法便可。

5) public stiatc boolean isMultipartContent(HttpServletRequest req)
        isMultipartContent方法方法用於判斷請求消息中的內容是不是「multipart/form-data」類型,是則返回true,不然返回false。isMultipartContent方法是一個靜態方法,不用建立ServletFileUpload類的實例對象便可被調用。

6) getFileItemFactory()和setFileItemFactory(FileItemFactory)
       方法繼承自FileUpload類,用於設置和讀取fileItemFactory屬性。

7) public void setProgressListener(ProgressListener pListener)
      設置文件上傳進度監聽器。該方法有一個對應的讀取方法:ProgressListener getProgressListener()。

8) public void setHeaderEncoding()
       在文件上傳請求的消息體中,除了普通表單域的值是文本內容之外,上傳文件中的文件路徑名也是文本(包括文件名),在內存中保存的是它們的某種字符集編碼的字節數組,Apache文件上傳組件在讀取這些內容時,必須知道它們所採用的字符集編碼,才能將它們轉換成正確的字符文本返回。

        setHeaderEncoding方法繼承自FileUploadBase類,用於設置上面提到的字符編碼。若是沒有設置,則對應的讀方法getHeaderEncoding()方法返回null,將採用HttpServletRequest設置的字符編碼,若是HttpServletRequest的字符編碼也爲null,則採用系統默認字符編碼。能夠經過一下語句得到系統默認字符編碼:

         System.getProperty("file.encoding"));

 

DiskFileItemFactory類

 

 

 將請求消息實體中的每個項目封裝成單獨的DiskFileItem (FileItem接口的實現) 對象的任務
由 org.apache.commons.fileupload.FileItemFactory 接口的默認實現 
org.apache.commons.fileupload.disk.DiskFileItemFactory 來完成。當上傳的文件項目比較小時,直接保存在內存中(速度比較快),比較大時,以臨時文件的形式,保存在磁盤臨時文件夾(雖然速度慢些,可是內存資源是有限的)。

屬性
1) public static final int DEFAULT_SIZE_THRESHOLD :將文件保存在內存仍是磁盤臨時文件夾的默認臨界值,值爲10240,即10kb。

2) private File repository:用於配置在建立文件項目時,當文件項目大於臨界值時使用的臨時文件夾,默認採用系統默認的臨時文件路徑,能夠經過系統屬性 java.io.tmpdir獲取。以下代碼:

System.getProperty("java.io.tmpdir");

3) private int sizeThreshold:用於保存將文件保存在內存仍是磁盤臨時文件夾的臨界值

構造方法
1) public DiskFileItemFactory()

      採用默認臨界值和系統臨時文件夾構造文件項工廠對象。

2) public DiskFileItemFactory(int sizeThreshold,File repository)

      採用參數指定臨界值和系統臨時文件夾構造文件項工廠對象。

3) FileItem createItem() 
       根據DiskFileItemFactory相關配置將每個請求消息實體項目建立成DiskFileItem 實例,並返回。該方法歷來不須要咱們親自調用,FileUpload組件在解析請求時內部使用。

4) void setSizeThreshold(int sizeThreshold)
        Apache文件上傳組件在解析上傳數據中的每一個字段內容時,須要臨時保存解析出的數據,以便在後面進行數據的進一步處理(保存在磁盤特定位置或插入數據庫)。由於Java虛擬機默承認以使用的內存空間是有限的,超出限制時將會拋出「java.lang.OutOfMemoryError」錯誤。若是上傳的文件很大,例如800M的文件,在內存中將沒法臨時保存該文件內容,Apache文件上傳組件轉而採用臨時文件來保存這些數據;但若是上傳的文件很小,例如600個字節的文件,顯然將其直接保存在內存中性能會更加好些。

        setSizeThreshold方法用於設置是否將上傳文件已臨時文件的形式保存在磁盤的臨界值(以字節爲單位的int值),若是從沒有調用該方法設置此臨界值,將會採用系統默認值10KB。對應的getSizeThreshold() 方法用來獲取此臨界值。

5) void setRepository(File repository)
        setRepositoryPath方法用於設置當上傳文件尺寸大於setSizeThreshold方法設置的臨界值時,將文件以臨時文件形式保存在磁盤上的存放目錄。有一個對應的得到臨時文件夾的 File getRespository() 方法。

         注意:當從沒有調用此方法設置臨時文件存儲目錄時,默認採用系統默認的臨時文件路徑,能夠經過系統屬性 java.io.tmpdir 獲取。以下代碼:

System.getProperty("java.io.tmpdir");

Tomcat系統默認臨時目錄爲「<tomcat安裝目錄>/temp/」。

相關文章
相關標籤/搜索