標籤:word img 功能 orm www put 記憶體 字元 set
三個類:DiskFileUpload、FileItem和FileUploadException。這三個類全部位於org.apache.commons.fileupload包中。
首先需要說明一下form表格的enctpye的屬性:
表單中enctype="multipart/form-data"的意思,是設定表單的MIME編碼。預設情況,這個編碼格式是application/x-www-form-urlencoded,不能用於檔案上傳;只有使用了multipart/form-data,才能完整的傳遞檔案資料,
進行下面的操作.
enctype="multipart/form-data"是上傳位元據; form裡面的input的值以2進位的方式傳過去。
form裡面的input的值以2進位的方式傳過去,所以request就得不到值了。 也就是說加了這段代碼,用request就會傳遞不成功。
DiskFileUpload類
DiskFileUpload類是Apache檔案上傳組件的核心類,應用程式開發人員通過這個類來與Apache檔案上傳組件進行互動。
下面介紹DiskFileUpload類中的幾個常用的重要方法。
1.setSizeMax方法
setSizeMax方法用於佈建要求訊息實體內容的最大允許大小,以防止用戶端故意通過上傳特大的檔案來塞滿伺服器端的儲存空間,單位為位元組。
其完整文法定義如下:
public void setSizeMax(long sizeMax)
如果請求訊息中的實體內容的大小超過了setSizeMax方法的設定值,該方法將會拋出FileUploadException異常。
2.setSizeThreshold方法
Apache檔案上傳組件在解析和處理上傳資料中的每個欄位內容時,需要臨時儲存解析出的資料。
因為Java虛擬機器預設可以使用的記憶體空間是有限的(筆者測試不大於100M),超出限制時將會發生“java.lang.OutOfMemoryError”錯誤,
如果上傳的檔案很大,例如上傳800M的檔案,在記憶體中將無法儲存該檔案內容,Apache檔案上傳組件將用臨時檔案來儲存這些資料;
但如果上傳的檔案很小,例如上傳600個位元組的檔案,顯然將其直接儲存在記憶體中更加有效。
setSizeThreshold方法用於設定是否使用臨時檔案儲存解析出的資料的那個臨界值,該方法傳入的參數的單位是位元組。其完整文法定義如下:
public void setSizeThreshold(int sizeThreshold)
3. setRepositoryPath方法
setRepositoryPath方法用於設定setSizeThreshold方法中提到的臨時檔案的存放目錄,這裡要求使用絕對路徑。其完整文法定義如下:
public void setRepositoryPath(String repositoryPath)
如果不設定存放路徑,那麼臨時檔案將被儲存在"java.io.tmpdir"這個JVM環境屬性所指定的目錄中,tomcat 5.5.9將這個屬性設定為了“<tomcat安裝目錄>/temp/”目錄。
4. parseRequest方法
parseRequest 方法是DiskFileUpload類的重要方法,它是對HTTP請求訊息進行解析的入口方法,
如果請求訊息中的實體內容的類型不是“multipart/form-data”,該方法將拋出FileUploadException異常。
parseRequest 方法解析出FORM表單中的每個欄位的資料,並將它們分別封裝成獨立的FileItem對象,然後將這些FileItem對象加入進一個List類型的集合對象中返回。parseRequest 方法的完整文法定義如下:
public List parseRequest(HttpServletRequest req)
parseRequest 方法還有一個重載方法,該方法集中處理上述所有方法的功能,其完整文法定義如下:
parseRequest(HttpServletRequest req,int sizeThreshold,long sizeMax,
String path)
這兩個parseRequest方法都會拋出FileUploadException異常。
5. isMultipartContent方法
isMultipartContent方法方法用於判斷請求訊息中的內容是否是“multipart/form-data”類型,是則返回true,否則返回false。
isMultipartContent方法是一個靜態方法,不用建立DiskFileUpload類的執行個體對象即可被調用,其完整文法定義如下:
public static final boolean isMultipartContent(HttpServletRequest req)
6. setHeaderEncoding方法
由於瀏覽器在提交FORM表單時,會將普通表單中填寫的常值內容傳遞給伺服器,對於檔案上傳欄位,除了傳遞原始的檔案內容外,還要傳遞其檔案路徑名等資訊,
如後面的圖1.3所示。不管FORM表單採用的是“application/x-www-form-urlencoded”編碼,還是“multipart/form-data”編碼,
它們僅僅是將各個FORM表單欄位元素內容組織到一起的一種格式,而這些內容又是由某種字元集編碼來表示的。
關於瀏覽器採用何種字元集來編碼FORM表單欄位中的內容,請參看筆者編著的《深入體驗java Web開發內幕——核心基礎》一書中的第6.9.2的講解,
“multipart/form-data”類型的表單為表單欄位內容選擇字元集編碼的原理和方式與“application/x-www-form-urlencoded”類型的表單是相同的。
FORM表單中填寫的常值內容和檔案上傳欄位中的檔案路徑名在記憶體中就是它們的某種字元集編碼的位元組數組形式,Apache檔案上傳組件在讀取這些內容時,
必須知道它們所採用的字元集編碼,才能將它們轉換成正確的字元文本返回。
對於瀏覽器上傳給WEB伺服器的各個表單欄位的描述頭內容,Apache檔案上傳組件都需要將它們轉換成字串形式返回,
setHeaderEncoding 方法用於設定轉換時所使用的字元集編碼,其原理與筆者編著的《深入體驗java Web開發內幕——核心基礎》一書中的第6.9.4節講解的ServletRequest.setCharacterEncoding方法相同。
setHeaderEncoding 方法的完整文法定義如下:
public void setHeaderEncoding(String encoding)
其中,encoding參數用於指定將各個表單欄位的描述頭內容轉換成字串時所使用的字元集編碼。
注意:如果讀者在使用Apache檔案上傳組件時遇到了中文字元的亂碼問題,一般都是沒有正確調用setHeaderEncoding方法的原因。
FileItem類
FileItem類用來封裝單個表單欄位元素的資料,一個表單欄位元素對應一個FileItem對象,通過調用FileItem對象的方法可以獲得相關表單欄位元素的資料。
FileItem是一個介面,在應用程式中使用的實際上是該介面一個實作類別,該實作類別的名稱並不重要,程式可以採用FileItem介面類型來對它進行引用和訪問,為了便於講解,
這裡將FileItem實作類別稱之為FileItem類。FileItem類還實現了Serializable介面,以支援序列化操作。
對於“multipart/form-data”類型的FORM表單,瀏覽器上傳的實體內容中的每個表單欄位元素的資料之間用欄位分隔界線進行分割,兩個分隔界線間的內容稱為一個分區,
每個分區中的內容可以被看作兩部分,一部分是對錶單欄位元素進行描述的描述頭,另外一部是表單欄位元素的主體內容,1.3所示。
圖1.3
主體部分有兩種可能性,要麼是使用者填寫的表單內容,要麼是檔案內容。FileItem類對象實際上就是對圖1.3中的一個分區的資料進行封裝的對象,它內部用了兩個成員變數來分別儲存描述頭和主體內容,其中儲存主體內容的變數是一個輸出資料流類型的對象。當主體內容的大小小於DiskFileUpload.setSizeThreshold方法設定的臨界值大小時,這個流對象關聯到一片記憶體,主體內容將會被儲存在記憶體中。當主體內容的資料超過DiskFileUpload.setSizeThreshold方法設定的臨界值大小時,這個流對象關聯到硬碟上的一個臨時檔案,主體內容將被儲存到該臨時檔案中。臨時檔案的儲存目錄由DiskFileUpload.setRepositoryPath方法設定,臨時檔案名稱的格式為“upload_00000005(八位或八位以上的數字).tmp”這種形式,FileItem類內部提供了維護臨時檔案名稱中的數值不重複的機制,以保證了臨時檔案名稱的唯一性。當應用程式將主體內容儲存到一個指定的檔案中時,或者在FileItem對象被記憶體回收行程回收時,或者Java虛擬機器結束時,Apache檔案上傳組件都會嘗試刪除臨時檔案,以盡量保證臨時檔案能被及時清除。
下面介紹FileItem類中的幾個常用的方法:
1. isFormField方法
isFormField方法用於判斷FileItem類對象封裝的資料是否屬於一個普通表單欄位,還是屬於一個檔案表單欄位,如果是普通表單欄位則返回true,否則返回false。該方法的完整文法定義如下:
public boolean isFormField()
2. getName方法
getName方法用於獲得檔案上傳欄位中的檔案名稱,對於圖1.3中的第三個分區所示的描述頭,getName方法返回的結果為字串“C:\bg.gif”。如果FileItem類對象對應的是普通表單欄位,getName方法將返回null。即使使用者沒有通過網頁表單中的檔案欄位傳遞任何檔案,但只要設定了檔案表單欄位的name屬性,瀏覽器也會將檔案欄位的資訊傳遞給伺服器,只是檔案名稱和檔案內容部分都為空白,但這個表單欄位仍然對應一個FileItem對象,此時,getName方法返回結果為空白字串"",讀者在調用Apache檔案上傳組件時要注意考慮這個情況。getName方法的完整文法定義如下:
public String getName()
注意:如果使用者使用Windows系統上傳檔案,瀏覽器將傳遞該檔案的完整路徑,如果使用者使用Linux或者Unix系統上傳檔案,瀏覽器將只傳遞該檔案的名稱部分。
3.getFieldName方法
getFieldName方法用於返回表單欄位元素的name屬性值,也就是返回圖1.3中的各個描述頭部分中的name屬性值,例如“name=p1”中的“p1”。getFieldName方法的完整文法定義如下:
public String getFieldName()
4. write方法
write方法用於將FileItem對象中儲存的主體內容儲存到某個指定的檔案中。如果FileItem對象中的主體內容是儲存在某個臨時檔案中,該方法順利完成後,臨時檔案有可能會被清除。該方法也可將普通表單欄位內容寫入到一個檔案中,但它主要用途是將上傳的檔案內容儲存在本地檔案系統中。其完整文法定義如下:
public void write(File file)
5.getString方法
getString方法用於將FileItem對象中儲存的主體內容作為一個字串返回,它有兩個重載的定義形式:
public java.lang.String getString()
public java.lang.String getString(java.lang.String encoding)
throwsjava.io.UnsupportedEncodingException
前者使用預設的字元集編碼將主體內容轉換成字串,後者使用參數指定的字元集編碼將主體內容轉換成字串。如果在讀取普通表單欄位元素的內容時出現了中文亂碼現象,請調用第二個getString方法,並為之傳遞正確的字元集編碼名稱。
6. getContentType方法
getContentType 方法用於獲得上傳檔案的類型,對於圖1.3中的第三個分區所示的描述頭,getContentType方法返回的結果為字串“image/gif”,即“Content-Type”欄位的值部分。如果FileItem類對象對應的是普通表單欄位,該方法將返回null。getContentType 方法的完整文法定義如下:
public String getContentType()
7. isInMemory方法
isInMemory方法用來判斷FileItem類對象封裝的主體內容是儲存在記憶體中,還是儲存在臨時檔案中,如果儲存在記憶體中則返回true,否則返回false。其完整文法定義如下:
public boolean isInMemory()
8. delete方法
delete方法用來清空FileItem類對象中存放的主體內容,如果主體內容被儲存在臨時檔案中,delete方法將刪除該臨時檔案。儘管Apache組件使用了多種方式來盡量及時清理臨時檔案,但系統出現異常時,仍有可能造成有的臨時檔案被永久儲存在了硬碟中。在有些情況下,可以調用這個方法來及時刪除臨時檔案。其完整文法定義如下:
public void delete()
FileUploadException類
在檔案上傳過程中,可能發生各種各樣的異常,例如網路中斷、資料丟失等等。為了對不同異常進行合適的處理,Apache檔案上傳組件還開發了四個異常類,其中FileUploadException是其他異常類的父類,其他幾個類只是被間接調用的底層類,對於Apache組件調用人員來說,只需對FileUploadException異常類進行捕獲和處理即可。
檔案上傳到tomcat伺服器 commons-fileupload的詳細介紹與使用