學習的目標
使用commons-fileupload實現文件上傳
使用commons-fileupload封裝文件上傳工具類
什么是commons-fileupload?
The CommonsFileUploadpackage makes it easy to add robust, high-performance, file upload capability to your servlets and web applications.
FileUpload parses HTTP requests which conform toRFC 1867, "Form-based File Upload in HTML". That is, if an HTTP request is submitted using the POST method, and with a content type of "multipart/form-data", then FileUpload can parse that request, and make the results available in a manner easily used by the caller.
FileUpload包可以很容易地添加強大的,高性能,文件上傳到你的Servlet的Web應用程序的能力。
FileUpload解析HTTP請求符合RFC 1867年,“在HTML的文件上傳。就是說,如果一個HTTP請求是使用POST方法提交,並與一個內容類型“multipart/form-data”,然后FileUpload可以解析這個請求,並把結果提供一個容易使用的調用方式。
為什么要使用commons-fileupload
在使用傳統的Servlet上傳的時候我們可以使用req.getInputStream()來獲取文件上傳的流,我們在獲取到這個流之后需要手動的針對這個流進行特殊處理進行去流中不必要的開始和結束內容,才能真正的獲取到流的內容,本章節並不對原始Servlet的上傳進行探究,我們另開章節針對原始Servelt上傳進行探究。
使用commons-fileupload的要求
- method方法必須是POST,不能是GET
- 新加一個屬性enctype,值為”multipart/form-data”
- 文件表單項<input>的類型為file,即type=”file”
commons-fileupload的Maven依賴
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-io/commons-io --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency>
使用commons-fileupload核心步驟解讀
第一步:判斷是否可以進行文件上傳


第二步:創建一個FileItem工廠,通過工廠創建文件上傳核心組件ServletFileUpload對象


第三步:通過核心上傳組件解析request請求,獲取表單的所有表單項,表單的每一個表單項對應一個FileItem


第四步:遍歷所有的表單項,判斷是否是普通的表單項,如果不是就是文件上傳,就可以針對遍歷的這個fileItem進行一系列的操作


封裝一個工具類,讓我們在處理文件上傳的時候爽呀爽
在上面我們已經介紹過了使用commons-fileupload上傳文件的整個流程,所以我們就直接將這個流程封裝成一個工具類,在使用到文件上傳的Servlet中直接使用,十分便利
第一步:創建一個DTO(用於存儲commons-fileupload解析請求的結果)
import org.apache.commons.fileupload.FileItem; import java.util.HashMap; import java.util.Map; public class ParamDto { private Map<String,String> paramMap; private Map<String,FileItem> fileMap; public ParamDto() { paramMap = new HashMap<>(); fileMap = new HashMap<>(); } public Map<String, String> getParamMap() { return paramMap; } public void setParamMap(Map<String, String> paramMap) { this.paramMap = paramMap; } public Map<String, FileItem> getFileMap() { return fileMap; } public void setFileMap(Map<String, FileItem> fileMap) { this.fileMap = fileMap; } }
第二步:將commons-fileupload解析文件的整個請求,封裝成一個工具類
import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.imooc.dto.ParamDto; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.util.List; public class RequestUtil { /** * 從request流中解析參數與上傳的文件 * @param request */ public static ParamDto parseParam(HttpServletRequest request) { ParamDto result = new ParamDto(); //創建一個FileItem工廠 通過DiskFileItemFactory對象創建文件上傳核心組件 ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory()); upload.setHeaderEncoding("UTF-8"); try { //通過文件上傳核心組件解析request請求,獲取到所有的FileItem對象 List<FileItem> fileItemList = upload.parseRequest(request); //遍歷表單的所有表單項(FileItem) 並對其進行相關操作 for(FileItem fileItem : fileItemList) { //判斷這個表單項如果是一個普通的表單項 if(fileItem.isFormField()) { result.getParamMap().put(fileItem.getFieldName(),fileItem.getString("UTF-8")); //如果不是表單的普通文本域,就是 } else { result.getFileMap().put(fileItem.getFieldName(),fileItem); } } } catch (FileUploadException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return result; } }
第三步:讓我們直接在Servlet中使用這個工具類吧,哈哈


另:我們當然可以封裝一個保存文件(Item)的一個通用方法
import org.apache.commons.fileupload.FileItem; import java.io.File; public class FileUtil { /** * 上傳文件的保存路徑 */ public static final String SAVE_PATH = "d:/upload/"; /** * 保存上傳的文件 * @param fileItem * @param path * @return * @throws Exception */ public static String save(FileItem fileItem,String path) throws Exception { String fileName = System.currentTimeMillis() + "_" + fileItem.getName(); fileItem.write(new File(path + fileName)); return fileName; } }
好啦~ 有空我們再來看看原始的文件上傳方式