本系列部落格彙總在這裡:檔案上傳下載下傳彙總彙總
一、把上傳的檔案放到 WEB-INF 目錄下
二、中文亂碼問題
1、上傳檔案名稱中包含中文
2、上傳檔案的檔案内容包含中文
三、上傳檔案同名問題(檔案重命名)
四、上傳的單個檔案的大小限制
五、上傳檔案的總大小限制
六、緩存大小與臨時目錄
如果沒有把使用者上傳的檔案存放到 WEB-INF 目錄下,那麼使用者就可以通過浏覽器直接通路上傳的檔案,這是非常危險的!!!
假如說使用者上傳了一個 a.jsp 檔案,然後使用者在通過浏覽器去通路這個 a.jsp 檔案,那麼就會執行 a.jsp 中的内容,如果在 a.jsp 中有如下語句:
<code>Runtime.getRuntime().exec(“shutdown –s –t 1”);</code>
那麼你就會…
通常我們會在 WEB-INF 目錄下建立一個 uploads 目錄來存放上傳的檔案,而在 Servlet 中找到這個目錄需要使用 ServletContext 的 getRealPath(String) 方法,例如在我的 file_upload1 項目中有如下語句:

當上傳的誰的名稱中包含中文時,需要設定編碼,commons-fileupload 元件為我們提供了兩種設定編碼的方式:
<code>request.setCharacterEncoding(String);</code>:這種方式是我們最為熟悉的方式了;
<code>fileUpload.setHeaderEncdoing(String);</code>:這種方式的優先級高與前一種。
通常我們不需關心上傳檔案的内容,因為我們會把上傳檔案儲存到硬碟上!也就是說,檔案原來是什麼樣子,到伺服器這邊還是什麼樣子!但是如果你有這樣的需求,非要在控制台顯示上傳的檔案内容,那麼你可以使用<code>fileItem.getString(“utf-8”)</code> 來處理編碼。文本檔案内容和普通表單項内容使用 FileItem 類的 getString(“utf-8”) 來處理編碼。
通常我們會把使用者上傳的檔案儲存到 uploads 目錄下,但如果使用者上傳了同名檔案呢?這會出現覆寫的現象。處理這一問題的手段是使用 UUID 生成唯一名稱,然後再使用 “_” 連接配接檔案上傳的原始名稱。例如使用者上傳的檔案是 “我的一寸照片.jpg”,在通過處理後,檔案名稱為:“891b3881395f4175b969256a3f7b6e10_我的一寸照片.jpg”,這種手段不會使檔案丢失擴充名,并且因為 UUID 的唯一性,上傳的檔案同名,但在伺服器端是不會出現同名問題的。
限制上傳檔案的大小很簡單,ServletFileUpload 類的 <code>setFileSizeMax(long)</code> 就可以了。參數就是上傳檔案的上限位元組數,例如 <code>servletFileUpload.setFileSizeMax(1024*10)</code> 表示上限為10KB。 一旦上傳的檔案超出了上限,那麼就會抛出<code>FileUploadBase.FileSizeLimitExceededException</code> 異常。我們可以在 Servlet 中擷取這個異常,然後向頁面輸出 “上傳的檔案超出限制”。
上傳檔案的表單中可能允許上傳多個檔案,例如:
這時我們需要限制一個請求的大小。也就是說這個請求的最大位元組數(所有表單項之和)!實作這一功能也很簡單,隻需要調用 ServletFileUpload 類的 setSizeMax(long) 方法即可。例如 <code>fileUpload.setSizeMax(1024 * 10);</code>,顯示整個請求的上限為 10KB。當請求大小超出10KB 時,ServletFileUpload 類的 <code>parseRequest()</code> 方法會抛出<code>FileUploadBase.SizeLimitExceededException</code> 異常。
大家想一想,如果我上傳一個藍光電影,先把電影儲存到記憶體中,然後再通過記憶體 copy 到伺服器硬碟上,那麼你的記憶體能吃的消麼?是以 fileupload 元件不可能把檔案都儲存在記憶體中,fileupload 會判斷檔案大小是否超出10KB,如果是那麼就把檔案儲存到硬碟上,如果沒有超出,那麼就儲存在記憶體中。10KB是 fileupload 預設的值,我們可以來設定它。當檔案儲存到硬碟時,fileupload 是把檔案儲存到系統臨時目錄,當然你也可以去設定臨時目錄。
如果需要本文當中涉及的完整代碼,請下載下傳彙總處的項目檔案。
如有錯誤,歡迎指正!