標籤:
基於表單的檔案上傳1. 進行檔案上傳時, 表單需要做的準備:
1). 請求方式為 POST: <form action="uploadServlet" method="post" ... >
2). 使用 file 的表單域: <input type="file" name="file"/>
3). 使用 multipart/form-data 的請求編碼方式: <form action="uploadServlet" method="post" enctype="multipart/form-data">
<form action="uploadServlet" method="post" enctype="multipart/form-data">File: <input type="file" name="file"/><input type="submit" value="Submit"/></form>
4). 關於 enctype:
> application/x-www-form-urlencoded:表單 enctype 屬性的預設值。這種編碼方案使用有限的字元集,當使用了非字母和數字時,必須用”%HH”代替(H 代表十六進位數字)。對於大容量的位元據或包含非 ASCII 字元的文本來說,這種編碼不能滿足要求。
> multipart/form-data:form 設定了enctype=“multipart/form-data”屬性後,表示表單以二進位傳輸資料
2. 服務端:
1). 不能再使用 request.getParameter() 等方式擷取請求資訊. 擷取不到, 因為請求的編碼方式已經改為 multipart/form-data, 以二進位的方式來提交請求資訊.
2). 可以使用輸入資料流的方式來擷取. 但不建議這樣做.
3). 具體使用 commons-fileupload 組件來完成檔案的上傳操作.
I. 搭建環境: 加入
commons-fileupload-1.2.1.jar
commons-io-2.0.jar
II. 基本思想:
> commons-fileupload 可以解析請求, 得到一個 FileItem 對象組成的 List
> commons-fileupload 把所有的請求資訊都解析為 FileItem 對象, 無論是一個一般的文本域還是一個檔案域.
> 可以調用 FileItem 的 isFormField() 方法來判斷是一個 表單域 或不是表單域(則是一個檔案域)
> 再來進一步擷取資訊
if (item.isFormField()) { String name = item.getFieldName(); String value = item.getString(); ... } if (!item.isFormField()) { String fieldName = item.getFieldName(); String fileName = item.getName(); String contentType = item.getContentType(); boolean isInMemory = item.isInMemory(); long sizeInBytes = item.getSize(); InputStream uploadedStream = item.getInputStream(); ... uploadedStream.close(); }
III. 如何得到 List<FileItem> 對象.
> 簡單的方式
// Create a factory for disk-based file items FileItemFactory factory = new DiskFileItemFactory(); // Create a new file upload handler ServletFileUpload upload = new ServletFileUpload(factory); // Parse the request List /* FileItem */ items = upload.parseRequest(request);
> 複雜的方式: 可以為檔案的上傳加入一些限制條件和其他的屬性
// Create a factory for disk-based file items DiskFileItemFactory factory = new DiskFileItemFactory(); //設定記憶體中最多可以存放的上傳檔案的大小, 若超出則把檔案寫到一個臨時檔案夾中. 以 byte 為單位 factory.setSizeThreshold(yourMaxMemorySize); //設定那個臨時檔案夾 factory.setRepository(yourTempDirectory); // Create a new file upload handler ServletFileUpload upload = new ServletFileUpload(factory); //設定上傳檔案的總的大小. 也可以設定單個檔案的大小. upload.setSizeMax(yourMaxRequestSize); // Parse the request List /* FileItem */ items = upload.parseRequest(request);
檔案的下載:步驟:
I. 設定 contentType 回應標頭: 設定響應的類型是什麼 ? 通知瀏覽器是個下載的檔案
response.setContentType("application/x-msdownload");
II. 設定 Content-Disposition 回應標頭: 通知瀏覽器不再有瀏覽器來自行處理(或開啟)要下載的檔案, 而由使用者手工完成
response.setHeader("Content-Disposition", "attachment;filename=abc.txt");
III. 具體的檔案: 可以調用 response.getOutputStream 的方式, 以 IO 流的方式發送給用戶端.
OutputStream out = response.getOutputStream();String pptFileName = "C:\\Users\\Think Pad\\Desktop\\11.JavaWEB_監聽器.pptx";InputStream in = new FileInputStream(pptFileName);byte [] buffer = new byte[1024];int len = 0;while((len = in.read(buffer)) != -1){ out.write(buffer, 0, len);}in.close(); 如何修改小工具或架構的原始碼 ?
1). 原則: 能不修改就不修改.
2). 修改的方法:
> 修改原始碼, 替換 jar 包中對應的 class 檔案.
> 在本地建立相同的包, 和類, 在這個類中修改即可.
檔案的上傳下載