Spring文件上傳,包括一次選中多個文件

爲方便演示, 全部處理邏輯所有放在Controller完成, 再也不寫Service等各層接口及實現. 如需在Service層處理, 思路及方法也是徹底同樣的.html


先說前臺. 運行之後就是這樣子的. 一個很是簡單的表單頁面, 兩個文件上傳按鈕, 一個提交java



其中單個文件上傳, 即只能選擇一個文件, 沒法同時選擇多個web



相對的, 多個文件就是能夠同時選擇多個文件了
spring



文件選擇之後就是這個樣子apache



代碼以下: 一個form, 文件上傳就是一個<input>輸入, 屬性type="file". 此時只能選擇單個文件. 然後面加一個multiple, 便可同時選擇多個文件app


action屬性中的路徑後綴爲.htm, 是由於個人環境中配置了映射, 因此要在Controller中指定的路徑後添加一個.htm後綴, 不然系統會報404. 若是沒有配置該項則無需添加後綴
ide

[html] view plain copy post

  1. <body>  測試

  2.     <form action="${pageContext.request.contextPath}/test/upload.htm" enctype="multipart/form-data" method="post">  編碼

  3.         單個文件: <input type="file" name="fileTest"><br/>  

  4.         多個文件: <input type="file" name="fileList" multiple/></br/>  

  5.         <input type="submit" value="提交" />  

  6.     </form>  

  7. </body>  


另外一點須要注意的是, 要實現文件上傳, form中必須指定屬性enctype="multipart/form-data". method屬性爲"post"


前臺就這些東西了, 沒什麼特殊的. 而後再看後臺


首先Spring配置文件中加這麼一個bean

[html] view plain copy

  1. <bean id="multipartResolver"  

  2.     class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  

  3.     <!-- 默認編碼 -->  

  4.     <property name="defaultEncoding" value="utf-8" />  

  5.     <!-- 文件大小最大值 -->  

  6.     <property name="maxUploadSize" value="10485760" />  

  7.     <!-- 內存中的最大值 -->  

  8.     <property name="maxInMemorySize" value="40960" />  

  9. </bean>  


也能夠在代碼中直接建立對象

[java] view plain copy

  1. CommonsMultipartResolver commonsMultipartResolver = new   CommonsMultipartResolver(request.getSession().getServletContext());  

可是我的認爲配置之後使用比較方便, 各位根據實際須要來吧


其中maxUploadSize屬性用來設計上傳文件的最大值, 單位是字節. 注意這裏是總的上傳限制, 好比設置爲10M, 上傳了4個3M的文件. 雖然單個文件都在10M之內, 可是總大小已經超過10M限制, 會拋出MaxUploadSizeExceededException異常


[java] view plain copy

  1. package com.test.controller;  

  2.   

  3. import java.io.File;  

  4. import java.io.IOException;  

  5. import java.util.Iterator;  

  6. import java.util.List;  

  7.   

  8. import org.springframework.stereotype.Controller;  

  9. import org.springframework.web.bind.annotation.RequestMapping;  

  10. import org.springframework.web.bind.annotation.ResponseBody;  

  11. import org.springframework.web.multipart.MultipartFile;  

  12. import org.springframework.web.multipart.MultipartHttpServletRequest;  

  13.   

  14. /** 

  15.  * 文件上傳測試類 

  16.  */  

  17. @Controller  

  18. @RequestMapping("/test")  

  19. public class FileUploadController {  

  20.   

  21.     @ResponseBody  

  22.     @RequestMapping(value="upload")  

  23.     public void testUpload(MultipartHttpServletRequest request) throws IOException {  

  24.         /* 

  25.          * MultipartHttpServletRequest: 繼承於HttpServletRequest以及MultipartRequest. 

  26.          * 其中MultipartRequest中定義了相關的訪問操做. MultipartHttpServletRequest重寫 

  27.          * 了HttpServletRequest中的方法, 並進行了擴展. 若是以HttpServletRequest來接收參 

  28.          * 數, 則須要先將其轉爲MultipartHttpServletRequest類型 

  29.          * MultipartHttpServletRequest request = (MultipartHttpServletRequest) HttpServletRequest; 

  30.          */  

  31.           

  32.         /* 

  33.          * 再說回剛纔的form, 假設咱們在單個文件選框中上傳了文件1, 多個文件選框中上傳了文件2, 3, 4. 

  34.          * 那麼對於後臺接收到的, 能夠這麼理解, 就是一個Map的形式(實際上它後臺真的是以Map來存儲的). 

  35.          * 這個Map的Key是什麼呢? 就是上面<input>標籤中的name=""屬性. Value則是咱們剛纔上傳的 

  36.          * 文件, 經過下面的示例能夠看出每個Value就是一個包含對應文件集合的List 

  37.          *  

  38.          * 傳到後臺接收到的Map就是這樣: 

  39.          * fileTest: 文件1 

  40.          * fileList: 文件2, 文件3, 文件4 

  41.          *  

  42.          * 雖然從方法名的表面意義來看是獲得文件名, 但實際上這個文件名跟上傳的文件自己並無什麼關係. 

  43.          * 剛纔說了這個Map的Key就是<input>標籤中的name=""屬性, 因此獲得的也就是這個屬性的值 

  44.          */  

  45.         Iterator<String> fileNames = request.getFileNames();  

  46.           

  47.         while (fileNames.hasNext()) {  

  48.               

  49.             //把fileNames集合中的值打出來  

  50.             String fileName=fileNames.next();  

  51.             System.out.println("fileName: "+fileName);  

  52.               

  53.             /* 

  54.              * request.getFiles(fileName)方法即經過fileName這個Key, 獲得對應的文件 

  55.              * 集合列表. 只是在這個Map中, 文件被包裝成MultipartFile類型 

  56.              */  

  57.             List<MultipartFile> fileList=request.getFiles(fileName);  

  58.               

  59.             if (fileList.size()>0) {  

  60.                   

  61.                 //遍歷文件列表  

  62.                 Iterator<MultipartFile> fileIte=fileList.iterator();  

  63.                   

  64.                 while (fileIte.hasNext()) {  

  65.                       

  66.                     //得到每個文件  

  67.                     MultipartFile multipartFile=fileIte.next();  

  68.                       

  69.                     //得到原文件名  

  70.                     String originalFilename = multipartFile.getOriginalFilename();  

  71.                     System.out.println("originalFilename: "+originalFilename);  

  72.                       

  73.                     //設置保存路徑.   

  74.                     String path ="G:/testUpload/";  

  75.                       

  76.                     //檢查該路徑對應的目錄是否存在. 若是不存在則建立目錄  

  77.                     File dir=new File(path);  

  78.                     if (!dir.exists()) {  

  79.                         dir.mkdirs();  

  80.                     }  

  81.                       

  82.                     String filePath = path + originalFilename;  

  83.                     System.out.println("filePath: "+filePath);  

  84.                       

  85.                     //保存文件  

  86.                     File dest = new File(filePath);  

  87.                     if (!(dest.exists())) {  

  88.                         /* 

  89.                          * MultipartFile提供了void transferTo(File dest)方法, 

  90.                          * 將獲取到的文件以File形式傳輸至指定路徑. 

  91.                          */  

  92.                         multipartFile.transferTo(dest);  

  93.                           

  94.                         /* 

  95.                          * 若是需對文件進行其餘操做, MultipartFile也提供了 

  96.                          * InputStream getInputStream()方法獲取文件的輸入流 

  97.                          *  

  98.                          * 例以下面的語句即爲經過 

  99.                          * org.apache.commons.io.FileUtils提供的 

  100.                          * void copyInputStreamToFile(InputStream source, File destination) 

  101.                          * 方法, 獲取輸入流後將其保存至指定路徑 

  102.                          */  

  103.                         //FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), dest);  

  104.                     }  

  105.                       

  106.                     //MultipartFile也提供了其餘一些方法, 用來獲取文件的部分屬性  

  107.                       

  108.                     //獲取文件contentType  

  109.                     String contentType=multipartFile.getContentType();  

  110.                     System.out.println("contentType: "+contentType);  

  111.                       

  112.                     /* 

  113.                      * 獲取name 

  114.                      * 其實這個name跟上面提到的getFileName值是同樣的, 

  115.                      * 就是Map中Key的值. 即前臺頁面<input>中name="" 

  116.                      * 屬性. 可是上面的getFileName只是獲得這個Map的Key, 

  117.                      * 而Spring在處理上傳文件的時候會把這個值以name屬性 

  118.                      * 記錄到對應的每個文件. 若是須要從文件層面獲取這個 

  119.                      * 值, 則可使用該方法  

  120.                      */  

  121.                     String name=multipartFile.getName();  

  122.                     System.out.println("name: "+name);  

  123.                       

  124.                     //獲取文件大小, 單位爲字節  

  125.                     long size=multipartFile.getSize();  

  126.                     System.out.println("size: "+size);  

  127.                       

  128.                     System.out.println("---------------------------------------------------");  

  129.                 }  

  130.             }  

  131.         }  

  132.     }  

相關文章
相關標籤/搜索