通過Maven建立Spring MVC項目,引入了Spring相關jar依賴。
1、為了使用commons fileupload組件,需要在pom.xml中添加依賴;
<properties> <spring.version>3.0.7.RELEASE </spring.version> <junit.version>3.8.1</junit.version> <fileupload.version>1.2.2</fileupload.version> </properties> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>${fileupload.version}</version> </dependency>
2、配置Spring MVC,項目成功啟動后,編寫jsp頁面;
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Errors導入Excel</title> </head> <body> <div> <!--只有將表單的enctype設置為multipart/form-data,才能實現文件上傳;表單enctype的默認值為:application/x-www-form-urlencoded--> <!--只有POST方法才會被解析為文件上傳請求 --> <form action="./fileupload" method="post" enctype="multipart/form-data"> <!-- 不知道為啥,type="file"這一標簽必須同時添加name屬性,否則在處理上傳時,無法檢測到上傳文件 --> <input type="file" name="fileField"/> <input type="submit" value="上傳"/> </form> <p><font color="red">上傳文件大小限制在1M之內</font></p> </div> </body> </html>
注:注釋當中的內容還是很重要的,使用時遇到了比較多奇葩的問題,暫時還未弄明白原因,留待日后解決。
注:實現上傳文件的表單,需要指定method="post"且enctype="multipart/form-data",否則無法通過fileupload組件解析為上傳請求。
3、編寫Controller,名為FileUploadController,在Controller中對上傳文件進行處理;
1 @Controller 2 public class FileUploadController { 3 4 @RequestMapping("/fileupload") 5 public String handleFileUpload(HttpServletRequest request){ 6 boolean flag = false; 7 8 //判斷是否是文件上傳請求 9 if(ServletFileUpload.isMultipartContent(request)){ 10 // 創建文件上傳處理器 11 ServletFileUpload upload = new ServletFileUpload(); 12 //限制單個上傳文件的大小 13 upload.setFileSizeMax(1L<<24); 14 15 try { 16 // 解析請求 17 FileItemIterator iter = upload.getItemIterator(request); 18 19 while (iter.hasNext()) { 20 FileItemStream item = iter.next(); 21 22 if (!item.isFormField()) { 23 //是文件上傳對象,獲取上傳文件的輸入流 24 InputStream srcinInputStream = item.openStream(); 25 /*對上傳文件的輸入流進行處理,跟本地的文件流處理方式相同*/ 26 27 } 28 } 29 } catch (FileUploadException e) { 30 System.out.println("上傳文件過大"); 31 } catch (IOException e) { 32 System.out.println("文件讀取出現問題"); 33 } 34 } 35 36 return flag? "success":"error"; 37 } 38 }
注:commons fileupload的用戶指南 http://commons.apache.org/proper/commons-fileupload/using.html;
注:判斷上傳請求及處理使用了Streaming API http://commons.apache.org/proper/commons-fileupload/streaming.html;
內容如下:

注:第一次看commons fileupload組件的用戶指南時,感覺無從下手,其實User Guide的Parsing the request部分已經給出了很明確的說明。可以通過在對應的請求處理方法中直接通過ServletFileUpload.isMultipartContent(request)來判斷是否是文件上傳請求,通過 !item.isFormField() 來判斷是否是文件上傳對象;
4、fileupload組件上傳文件時,獲取普通域參數值和文件域輸入流;
html元素的form表單的enctype屬性規定在發送到服務器之前應該如何對表單數據進行編碼。表單的enctype默認值為 "application/x-www-form-urlencoded",在表單發送到服務器之前,所有字符都會進行編碼(空格轉換為 "+" 加號,特殊符號轉換為 ASCII HEX 值);對於文件上傳,form表單的enctype="multipart/form-data",此時form表單不對字符編碼,此時在請求的處理函數中無法通過request.getParameter("parameterName")來獲取參數值;
但是可以通過其他方式來獲取參數值;
1 /** 2 * 獲取頁面傳遞的參數,以Map存儲,以fieldName為鍵值,普通域存儲value,文件上傳域存儲文件輸入流 3 * @param request 4 * @return 5 */ 6 private Map<String, Object> getParameters(HttpServletRequest request){ 7 Map<String, Object> parameters = new HashMap<String, Object>(); 8 9 // 默認最多允許存儲1024個字節 10 DiskFileItemFactory factory = new DiskFileItemFactory(); 11 12 if(ServletFileUpload.isMultipartContent(request)){ 13 ServletFileUpload upload = new ServletFileUpload(factory); 14 15 try{ 16 List<FileItem> items =upload.parseRequest(request); 17 18 for(Iterator<FileItem> iter = items.iterator(); iter.hasNext();){ 19 FileItem item = iter.next(); 20 21 if(item.isFormField()){ 22 //普通域,取參數值 23 parameters.put(item.getFieldName(), item.getString()); 24 }else{ 25 //文件上傳域,取輸入流 26 parameters.put(item.getFieldName(), item.getInputStream()); 27 } 28 } 29 }catch(Exception exception){ 30 exception.printStackTrace(); 31 } 32 } 33 34 return parameters; 35 }
