背景:html
http://www.cnblogs.com/lixuwu/p/8495275.html已經實現了單文件的上傳和下載,多文件的上傳是另外一種情景,這裏記錄下來java
先說前臺. 運行之後就是這樣子的. 一個很是簡單的表單頁面, 兩個文件上傳按鈕, 一個提交web
其中單個文件上傳, 即只能選擇一個文件, 沒法同時選擇多個spring
相對的, 多個文件就是能夠同時選擇多個文件了apache
文件選擇之後就是這個樣子app
代碼以下: 一個form, 文件上傳就是一個<input>輸入, 屬性type="file". 此時只能選擇單個文件. 然後面加一個multiple, 便可同時選擇多個文件less
jsp頁面multiFile.jsp: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>Insert title here</title> </head> <body> <form action="${pageContext.request.contextPath}/test/upload" enctype="multipart/form-data" method="post"> 單個文件: <input type="file" name="fileTest"><br/> 多個文件: <input type="file" name="fileList" multiple/></br/> <input type="submit" value="提交" /> </form> </body> </html>
spring中文件控制bean:ide
package spring.boot.uploadfile.config; import javax.servlet.MultipartConfigElement; import org.springframework.boot.web.servlet.MultipartConfigFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportResource; /** * ClassName:ConfigClass <br/> * Function: TODO <br/> * Date: 2018年3月2日 下午8:20:05 <br/> * @author prd-lxw * @version 1.0 * @since JDK 1.7 * @see */ /** * classpath路徑:locations={"classpath:application-bean1.xml","classpath:application-bean2.xml"} * file路徑: locations = {"file:d:/test/application-bean1.xml"}; */ @Configuration @ImportResource(locations = { "classpath:spring-web.xml" }) //@ImportResource(locations={"file:d:/test/application-bean1.xml"}) public class ConfigClass { @Bean public MultipartConfigElement multipartConfigElement() { MultipartConfigFactory factory = new MultipartConfigFactory(); //文件最大 factory.setMaxFileSize("1000240KB"); //KB,MB /// 設置總上傳數據總大小 factory.setMaxRequestSize("102400KB"); return factory.createMultipartConfig(); } }
Controller層代碼:post
/** * Project Name:uploadfile * File Name:MutilFileUploadController.java * Package Name:spring.boot.uploadfile.controller * Date:2018年3月2日下午9:50:25 * Copyright (c) 2018, 深圳金融電子結算中心 All Rights Reserved. * */ package spring.boot.uploadfile.controller; import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; /** * ClassName:MutilFileUploadController <br/> * Function: TODO <br/> * Date: 2018年3月2日 下午9:50:25 <br/> * @author prd-lxw * @version 1.0 * @since JDK 1.7 * @see */ /** * 文件上傳測試類 */ @Controller @RequestMapping("/test") public class MutilFileUploadController { @RequestMapping("multi") public String multiIndex() { return "multiFile"; } @ResponseBody @RequestMapping(value = "upload") public void testUpload(MultipartHttpServletRequest request) throws IOException { /* * MultipartHttpServletRequest: 繼承於HttpServletRequest以及MultipartRequest. * 其中MultipartRequest中定義了相關的訪問操做. MultipartHttpServletRequest重寫 * 了HttpServletRequest中的方法, 並進行了擴展. 若是以HttpServletRequest來接收參 * 數, 則須要先將其轉爲MultipartHttpServletRequest類型 * MultipartHttpServletRequest request = (MultipartHttpServletRequest) HttpServletRequest; */ /* * 再說回剛纔的form, 假設咱們在單個文件選框中上傳了文件1, 多個文件選框中上傳了文件2, 3, 4. * 那麼對於後臺接收到的, 能夠這麼理解, 就是一個Map的形式(實際上它後臺真的是以Map來存儲的). * 這個Map的Key是什麼呢? 就是上面<input>標籤中的name=""屬性. Value則是咱們剛纔上傳的 * 文件, 經過下面的示例能夠看出每個Value就是一個包含對應文件集合的List * * 傳到後臺接收到的Map就是這樣: * fileTest: 文件1 * fileList: 文件2, 文件3, 文件4 * * 雖然從方法名的表面意義來看是獲得文件名, 但實際上這個文件名跟上傳的文件自己並無什麼關係. * 剛纔說了這個Map的Key就是<input>標籤中的name=""屬性, 因此獲得的也就是這個屬性的值 */ Iterator<String> fileNames = request.getFileNames(); while (fileNames.hasNext()) { //把fileNames集合中的值打出來 String fileName = fileNames.next(); System.out.println("fileName: " + fileName); /* * request.getFiles(fileName)方法即經過fileName這個Key, 獲得對應的文件 * 集合列表. 只是在這個Map中, 文件被包裝成MultipartFile類型 */ List<MultipartFile> fileList = request.getFiles(fileName); if (fileList.size() > 0) { //遍歷文件列表 Iterator<MultipartFile> fileIte = fileList.iterator(); while (fileIte.hasNext()) { //得到每個文件 MultipartFile multipartFile = fileIte.next(); //得到原文件名 String originalFilename = multipartFile.getOriginalFilename(); System.out.println("originalFilename: " + originalFilename); //設置保存路徑. String path = "E:\\testJava\\filesss"; //檢查該路徑對應的目錄是否存在. 若是不存在則建立目錄 File dir = new File(path); if (!dir.exists()) { dir.mkdirs(); } String filePath = path + File.separator + originalFilename; System.out.println("filePath: " + filePath); //保存文件 File dest = new File(filePath); if (!(dest.exists())) { /* * MultipartFile提供了void transferTo(File dest)方法, * 將獲取到的文件以File形式傳輸至指定路徑. */ multipartFile.transferTo(dest); /* * 若是需對文件進行其餘操做, MultipartFile也提供了 * InputStream getInputStream()方法獲取文件的輸入流 * * 例以下面的語句即爲經過 * org.apache.commons.io.FileUtils提供的 * void copyInputStreamToFile(InputStream source, File destination) * 方法, 獲取輸入流後將其保存至指定路徑 */ //FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), dest); } //MultipartFile也提供了其餘一些方法, 用來獲取文件的部分屬性 //獲取文件contentType String contentType = multipartFile.getContentType(); System.out.println("contentType: " + contentType); /* * 獲取name * 其實這個name跟上面提到的getFileName值是同樣的, * 就是Map中Key的值. 即前臺頁面<input>中name="" * 屬性. 可是上面的getFileName只是獲得這個Map的Key, * 而Spring在處理上傳文件的時候會把這個值以name屬性 * 記錄到對應的每個文件. 若是須要從文件層面獲取這個 * 值, 則可使用該方法 */ String name = multipartFile.getName(); System.out.println("name: " + name); //獲取文件大小, 單位爲字節 long size = multipartFile.getSize(); System.out.println("size: " + size); System.out.println("---------------------------------------------------"); } } } } }
ps:上面的註釋很簡單,對照着實現就能夠了