(转)Spring文件上传,包括一次选中多个文件
背景:
http://www.cnblogs.com/lixuwu/p/8495275.html已经实现了单文件的上传和下载,多文件的上传是另一种情景,这里记录下来
实现过程
先说前台. 运行以后就是这样子的. 一个非常简单的表单页面, 两个文件上传按钮, 一个提交
其中单个文件上传, 即只能选择一个文件, 无法同时选择多个
相对的, 多个文件就是可以同时选择多个文件了
文件选择以后就是这个样子
前台设置
代码如下: 一个form, 文件上传就是一个<input>输入, 属性type="file". 此时只能选择单个文件. 而后面加一个multiple, 即可同时选择多个文件
jsp页面multiFile.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:
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层代码:
/** * 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:上面的注释很简单,对照着实现就可以了