1 、什麼是上傳和下載?
–  資料上傳是指客戶端向站群伺服器上傳資料,客戶端向站群伺服器傳送的所有請求都屬於資料上傳。檔案上傳是資料上傳的一種特例,指的是客戶端向站群伺服器上傳檔案。即將儲存在客戶端的檔案上傳至站群伺服器中的一個副本,儲存到站群伺服器中。
–   資料下載是指客戶端從站群伺服器上獲取資料的過程。檔案下載是資料下載的一種特例,指的是客戶端從站群伺服器下載檔案,即將原來儲存在站群伺服器中的檔案下載到客戶端中一個副本儲存。通常我們對站群伺服器所發出的請求,大多數是檔案下載請求,從站群伺服器中下載文字、圖片、聲音、視訊等檔案,然後由客戶端瀏覽器對這些檔案進行解析後,才可能看到這些多媒體資訊。
–  但是我們這裡所說的檔案下載,指的是檔案從站群伺服器下載到瀏覽器後,瀏覽器並不直接解析,而是以附件的形式儲存到客戶端中。
–  上傳與下載的檔案可以是文字檔案、圖片、聲音、視訊等各種型別。

2 、檔案上傳的實現:
a 、上傳時對錶單的要求:
–  檔案上傳要求客戶端表單提交特殊的請求–multipart 請求,即包含多部分資料的請求。所以檔案上傳表單對於表單資料的編碼型別要求,必須為 multipart/form-data 。即要為

標籤指定 enctype 屬性值為 “multipart/form-data” 。(enctype,即 encodingtype,編碼型別。)
–  由於客戶端上傳檔案的大小是不確定的,所以 HTTP 協議規定,檔案上傳的資料要存放於請求正文中,而不能夠出現在 url 的位址列中,因為位址列中可以存放的資料量太小。也就是說,檔案上傳的表單,必須提交 POST 請求,而不能夠提交 GET 請求。

b 、使用第三方工具實現檔案上傳:
–  需要使用到兩個 jar 包:commons-fileupload-1.3.3.jar 和 commons-io-2.6.jar,jar 包可以在 apache 官網中下載(commons-fileupload-1.3.3.jar 依賴於 commons-io-2.6.jar,如果只使用 fileupload jar 包,會執行程式時會丟擲異常)
–  示例程式碼如下:
–  在 index.jsp 檔案中填寫的程式碼如下所示:

– 為 web 應用新增一個 Servlet,在 web.xml 檔案中新增配置資訊:

–  自定義 serlvet 類,在 doPost 方法中編寫簡單實現檔案上傳的程式碼:

–  啟動 web 應用,訪問 index.jsp,新增圖片後,點選 “上傳”,可以發現控制檯列印結果,在工作空間 web 專案的指定目錄可以看到圖片已經上傳:(在 Eclipse 中,預設會把 Web 專案放到 Eclipse 的工作空間下的.metadata.pluginsorg.eclipse.wst.server.coretmp0(或者是 tmp1)wtpwebapps 下)

–  FileUploadServlet 類中的程式碼相關解釋:(也包含使用 fileupload jar 包檔案上傳時的常用方法)
–  org.apache.commons.fileupload.disk.DiskFileItemFactory 類:預設的 FileItemFactory 實現類。這個實現建立 FileItem 例項(檔案條目)。如果是小條目,會將其存入記憶體中,如果是大條目,會將其存入硬碟中的臨時檔案。大小條目資料的臨界值,是可配置的。

–  setRepository(File repository) 方法:設定臨時儲存檔案(這個檔案大小大於指定配置臨界值)存放的目錄位置。
–  setSizeThreshold(int sizeThreshold) 方法:設定臨界值(單位為位元組),當超過這個值時檔案將會直接寫入硬碟中。(如 sizeThreshold 為 1024 * 1024,則為 1 兆)

–  org.apache.commons.fileupload.servlet.ServletFileUpload 類:處理檔案上傳的高階 API 。(如何儲存各個部分的資料是由建立它們的工廠決定;給定的部分可能在記憶體中、磁碟上或者其他地方)

–  parseRequest 方法:解析請求,獲取 FileItem 型別元素的 List 物件:

–  ServletFileUpload 類的父類 org.apache.commons.fileupload.FileUploadBase 的方法:
–  設定每個 item 的頭部字元編碼,其可以解決檔名的中文亂碼問題:(若 tomcat 版本較低時,可能會出現檔名中文亂碼)

–  setFileSizeMax(long fileSizeMax) 方法設定單個上傳檔案允許上傳的最大邊界值。
–  setSizeMax(long sizeMax) 方法設定一次上傳所有檔案的總和最大邊界值。(單位都為位元組)

–  isMultipartContent(HttpServletRequest request) 方法:判斷該請求是否包含 multipart 內容

–  org.apache.commons.fileupload.FileItem 介面:表示在 multipart/form-data 的 POST 請求中內的一個檔案或者表單條目。

–  isFormField 方法:判斷 FileItem 例項是否為一個普通 form 項:

–  getFieldName 方法:獲取對應檔案條目(即單個表單項)的 name 屬性值:

–  getName 方法:獲取客戶端檔案系統中的原上傳檔名:(包含字尾名)

–  getInputStream 方法:獲取輸入流,用於取出上傳檔案中的內容:

–  delete 方法:刪除任何相關聯的臨時磁碟檔案:

3 、檔案下載的實現:
a 、超連結下載:將下載資源作為超連結的連結目標檔案出現。若瀏覽器可以解析該資原始檔,則將在瀏覽器上直接顯示檔案內容;若瀏覽器不支援該檔案的解析,則會彈出另存為對話方塊,要求使用者儲存。
–  該下載方式的缺點很明顯,不同的瀏覽器,以及相同的瀏覽器所安裝的外掛外掛不同,那麼其對於資源的解析能力也就不同,其是否彈出另存為對話方塊的情況也就不一樣。決定權由瀏覽器掌握。
–  如在 jsp 檔案中新增如下程式碼,在 ff 瀏覽器中點選,直接在瀏覽器中開啟該圖片:

b 、 Servlet 方式的檔案下載:
–  示例程式碼:
–  jsp 檔案中的內容和 web.xml 檔案中新增的配置:

–  自定義 Servlet 類中新增如下程式碼:

–  如果想要瀏覽器下載的方式是以附件的形式下載,需要修改響應的頭部屬性 content-disposition 值為 attachment;filename=檔名 + 字尾名。(filename 表示以附件形式下載顯示的檔名)

javax.servlet.ServletContext 介面的 getResourceAsStream 方法:獲取 web 應用中的指定路徑下的資源,以位元組輸入流 InputStream 的形式返回。

–  啟動 web 應用,點選超連結後,可以看到檔案以附件的形式下載:

4 、附加說明:
–  上傳檔案目錄的管理:當使用者上傳的檔案過多,而單個目錄能夠存放的檔案個數有限,(windows 系統下單資料夾中最大可有 65,534 個檔案)所以需要上傳的檔案有時需要分目錄進行管理。
–   可以使用 java.io.File 類的 mkdir() 方法來在當前目錄中建立直接子目錄,或者使用 mkdirs() 方法建立當前目錄的多層子目錄: