转:SpringBoot实现MultipartFile文件上传 - 云+社区 - 腾讯云 (tencent.com)
1、SpringBoot采用FileUpload组件实现上传处理,在控制器中可以使用MultipartFile类进行接收。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 5 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 6 <modelVersion>4.0.0</modelVersion> 7 <parent> 8 <groupId>org.springframework.boot</groupId> 9 <artifactId>spring-boot-starter-parent</artifactId> 10 <version>2.3.5.RELEASE</version> 11 <relativePath /> <!-- lookup parent from repository --> 12 </parent> 13 <groupId>com.example</groupId> 14 <artifactId>demo</artifactId> 15 <version>0.0.1-SNAPSHOT</version> 16 <name>demo</name> 17 <description>Demo project for Spring Boot</description> 18 19 <properties> 20 <java.version>1.8</java.version> 21 <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version> 22 </properties> 23 24 <dependencies> 25 <dependency> 26 <groupId>org.springframework.boot</groupId> 27 <artifactId>spring-boot-starter-web</artifactId> 28 </dependency> 29 30 <dependency> 31 <groupId>org.springframework.boot</groupId> 32 <artifactId>spring-boot-starter-test</artifactId> 33 <scope>test</scope> 34 <exclusions> 35 <exclusion> 36 <groupId>org.junit.vintage</groupId> 37 <artifactId>junit-vintage-engine</artifactId> 38 </exclusion> 39 </exclusions> 40 </dependency> 41 <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator --> 42 <dependency> 43 <groupId>org.hibernate</groupId> 44 <artifactId>hibernate-validator</artifactId> 45 <version>6.1.0.Final</version> 46 </dependency> 47 <dependency> 48 <groupId>org.springframework.boot</groupId> 49 <artifactId>spring-boot-starter-thymeleaf</artifactId> 50 </dependency> 51 </dependencies> 52 53 <build> 54 <plugins> 55 <plugin> 56 <groupId>org.springframework.boot</groupId> 57 <artifactId>spring-boot-maven-plugin</artifactId> 58 </plugin> 59 </plugins> 60 <resources> 61 <resource> 62 <directory>src/main/resources</directory> 63 <includes> 64 <include>**/*.properties</include> 65 <include>**/*.yml</include> 66 <include>**/*.xml</include> 67 <include>**/*.p12</include> 68 <include>**/*.html</include> 69 <include>**/*.jpg</include> 70 <include>**/*.png</include> 71 </includes> 72 </resource> 73 </resources> 74 </build> 75 76 </project>
创建控制器类UploadController,利用MultipartFile将上传文件保存在本地磁盘。
1 package com.demo.controller; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.util.HashMap; 6 import java.util.Map; 7 import java.util.UUID; 8 9 import org.springframework.stereotype.Controller; 10 import org.springframework.web.bind.annotation.RequestMapping; 11 import org.springframework.web.bind.annotation.RequestMethod; 12 import org.springframework.web.bind.annotation.RequestParam; 13 import org.springframework.web.bind.annotation.ResponseBody; 14 import org.springframework.web.context.request.RequestAttributes; 15 import org.springframework.web.context.request.RequestContextHolder; 16 import org.springframework.web.context.request.ServletRequestAttributes; 17 import org.springframework.web.multipart.MultipartFile; 18 19 /** 20 * 21 * @author 22 * 23 */ 24 @Controller 25 public class UploadController { 26 27 /** 28 * 首先根据此方法跳转到upload.html界面 29 * 30 * @return 31 */ 32 @RequestMapping(value = "/upload_pre", method = RequestMethod.GET) 33 public String uploadPre() { 34 return "upload"; 35 } 36 37 /** 38 * 文件上传 39 * 40 * @param name 41 * @param multipartFile 42 * @return 43 * @throws IllegalStateException 44 * @throws IOException 45 */ 46 @RequestMapping(value = "/upload", method = RequestMethod.POST) 47 @ResponseBody 48 public Object upload(String name, @RequestParam(value = "multipartFile") MultipartFile multipartFile) 49 throws IllegalStateException, IOException { 50 Map<String, Object> map = new HashMap<String, Object>(); 51 if (multipartFile != null) { 52 // 设置文件名称 53 map.put("nameParam", name); 54 // 设置文件名称 55 map.put("fileame", multipartFile.getName()); 56 // 设置文件类型 57 map.put("contentType", multipartFile.getContentType()); 58 // 设置文件大小 59 map.put("fileSize", multipartFile.getSize()); 60 // 创建文件名称 61 String fileName = UUID.randomUUID() + "." 62 + multipartFile.getContentType().substring(multipartFile.getContentType().lastIndexOf("/") + 1); 63 // 获取到文件的路径信息 64 RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); 65 ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes; 66 String filePath = servletRequestAttributes.getRequest().getServletContext().getRealPath("/") + fileName; 67 // 打印保存路径 68 System.out.println(filePath); 69 // 保存文件的路径信息 70 map.put("filePath", filePath); 71 // 创建文件 72 File saveFile = new File(filePath); 73 // 文件保存 74 multipartFile.transferTo(saveFile); 75 // 返回信息 76 return map; 77 } else { 78 return "no file "; 79 } 80 } 81 82 }
在src/main/resources/templates下面创建upload.html文件。
1 <!DOCTYPE html> 2 <html xmlns="http://www.thymeleaf.org"></html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>搞事情啊!!!</title> 6 </head> 7 <body> 8 <h1>搞事情啊!!!</h1> 9 10 <form th:action="@{/upload}" method="post" enctype="multipart/form-data"> 11 姓名:<input type="text" name="name"/><br/> 12 <!-- 切记,这里的name="multipartFile"必须和控制层的参数一致性MultipartFile multipartFile --> 13 照片:<input type="file" name="multipartFile"/><br/> 14 <input type="submit" value="上传"/><br/> 15 </form> 16 17 </body> 18 </html>
控制层类UploadController接收到此请求信息后,如果有上传文件存在,则会直接返回上传信息(开发者也可以根据情况选择将文件保存)。
演示效果,如下所示:
2、Springboot上传文件限制,在实际项目开发中,需要对用户上传文件的大小进行限制,这样才可以保证服务器的资源不被浪费。修改application.properties配置文件,如下所示:
1 # 启用http上传 2 spring.servlet.multipart.enabled=true 3 # 设置支持的单个上传文件的大小限制 4 spring.servlet.multipart.max-file-size=10MB 5 # 设置最大的请求文件大小,设置总体大小请求 6 spring.servlet.multipart.max-request-size=20MB 7 # 当上传文件达到指定配置量的时候,将文件内容写入磁盘 8 spring.servlet.multipart.file-size-threshold=512KB 9 # 设置上传的临时目录 10 spring.servlet.multipart.location=/
对于Springboot上传文件的上传限制,也可以利用Bean实现同样的效果,实现代码,如下所示:
1 package com.demo.config; 2 3 import javax.servlet.MultipartConfigElement; 4 5 import org.springframework.boot.web.servlet.MultipartConfigFactory; 6 import org.springframework.context.annotation.Bean; 7 import org.springframework.context.annotation.Configuration; 8 import org.springframework.util.unit.DataSize; 9 10 @Configuration 11 public class UploadConfig { 12 13 @Bean 14 public MultipartConfigElement getMultipartConfig() { 15 MultipartConfigFactory config = new MultipartConfigFactory(); 16 // 设置上传文件的单个大小限制 17 config.setMaxRequestSize(DataSize.parse("10MB")); 18 // 设置总的上传的大小限制 19 config.setMaxRequestSize(DataSize.parse("100MB")); 20 // 设置临时保存目录 21 config.setLocation("/"); 22 // 创建一个上传配置并返回 23 return config.createMultipartConfig(); 24 } 25 26 }
3、Springboot上传多个文件如果要进行多个文件的上传,需要通过MultipartHttpServletRequest进行文件接收。首先修改upload.html页面,定义多个文件上传控件。
1 <!DOCTYPE html> 2 <html xmlns="http://www.thymeleaf.org"></html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>搞事情啊!!!</title> 6 </head> 7 <body> 8 <h1>搞事情啊!!!</h1> 9 10 <form th:action="@{/upload}" method="post" enctype="multipart/form-data"> 11 姓名:<input type="text" name="name"/><br/> 12 <!-- 切记,这里的name="multipartFile"必须和控制层的参数一致性MultipartFile multipartFile --> 13 文件一:<input type="file" name="multipartFile"/><br/> 14 文件二:<input type="file" name="multipartFile"/><br/> 15 文件三:<input type="file" name="multipartFile"/><br/> 16 <input type="submit" value="上传"/><br/> 17 </form> 18 19 </body> 20 </html>
修改UploadController.java控制器,实现多个文件上传,此时可以根据接受参数的不同,方法可以有不同的实现 ,如果接受参数是这样的,@RequestParam(value = "multipartFile") MultipartFile[] multipartFile,实现代码,如下所示:
1 package com.demo.controller; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.util.HashMap; 6 import java.util.Map; 7 import java.util.UUID; 8 9 import org.springframework.stereotype.Controller; 10 import org.springframework.web.bind.annotation.RequestMapping; 11 import org.springframework.web.bind.annotation.RequestMethod; 12 import org.springframework.web.bind.annotation.RequestParam; 13 import org.springframework.web.bind.annotation.ResponseBody; 14 import org.springframework.web.context.request.RequestAttributes; 15 import org.springframework.web.context.request.RequestContextHolder; 16 import org.springframework.web.context.request.ServletRequestAttributes; 17 import org.springframework.web.multipart.MultipartFile; 18 19 /** 20 * 21 * @author 22 * 23 */ 24 @Controller 25 public class UploadController { 26 27 /** 28 * 首先根据此方法跳转到upload.html界面 29 * 30 * @return 31 */ 32 @RequestMapping(value = "/upload_pre", method = RequestMethod.GET) 33 public String uploadPre() { 34 return "upload"; 35 } 36 37 /** 38 * 文件上传 39 * 40 * @param name 41 * @param multipartFile 42 * @return 43 * @throws IllegalStateException 44 * @throws IOException 45 */ 46 @RequestMapping(value = "/upload", method = RequestMethod.POST) 47 @ResponseBody 48 public Object upload(String name, @RequestParam(value = "multipartFile") MultipartFile[] multipartFile) 49 throws IllegalStateException, IOException { 50 Map<String, Object> map = new HashMap<String, Object>(); 51 if (multipartFile != null && multipartFile.length > 0) { 52 for (int i = 0; i < multipartFile.length; i++) { 53 // 设置文件名称 54 map.put("nameParam", name); 55 // 设置文件名称 56 map.put("fileame", multipartFile[i].getName()); 57 // 设置文件类型 58 map.put("contentType", multipartFile[i].getContentType()); 59 // 设置文件大小 60 map.put("fileSize", multipartFile[i].getSize()); 61 // 创建文件名称 62 String fileName = UUID.randomUUID() + "." + multipartFile[i].getContentType() 63 .substring(multipartFile[i].getContentType().lastIndexOf("/") + 1); 64 // 获取到文件的路径信息 65 RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); 66 ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes; 67 String filePath = servletRequestAttributes.getRequest().getServletContext().getRealPath("/") + fileName; 68 // 打印保存路径 69 System.out.println(filePath); 70 // 保存文件的路径信息 71 map.put("filePath", filePath); 72 // 创建文件 73 File saveFile = new File(filePath); 74 // 文件保存 75 multipartFile[i].transferTo(saveFile); 76 // 返回信息 77 } 78 return map; 79 } else { 80 return "no file "; 81 } 82 } 83 84 }
如果接受参数是HttpServletRequest request,代码是这样的,明显没有第一种方便,如下所示:
1 package com.demo.controller; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.util.ArrayList; 6 import java.util.HashMap; 7 import java.util.Iterator; 8 import java.util.List; 9 import java.util.Map; 10 import java.util.UUID; 11 12 import javax.servlet.http.HttpServletRequest; 13 14 import org.springframework.stereotype.Controller; 15 import org.springframework.web.bind.annotation.RequestMapping; 16 import org.springframework.web.bind.annotation.RequestMethod; 17 import org.springframework.web.bind.annotation.RequestParam; 18 import org.springframework.web.bind.annotation.ResponseBody; 19 import org.springframework.web.context.request.RequestAttributes; 20 import org.springframework.web.context.request.RequestContextHolder; 21 import org.springframework.web.context.request.ServletRequestAttributes; 22 import org.springframework.web.multipart.MultipartFile; 23 import org.springframework.web.multipart.MultipartHttpServletRequest; 24 25 /** 26 * 27 * @author 28 * 29 */ 30 @Controller 31 public class UploadController { 32 33 /** 34 * 首先根据此方法跳转到upload.html界面 35 * 36 * @return 37 */ 38 @RequestMapping(value = "/upload_pre", method = RequestMethod.GET) 39 public String uploadPre() { 40 return "upload"; 41 } 42 43 /** 44 * 文件上传 45 * 46 * @param name 47 * @param multipartFile 48 * @return 49 * @throws IllegalStateException 50 * @throws IOException 51 */ 52 @RequestMapping(value = "/upload", method = RequestMethod.POST) 53 @ResponseBody 54 public Object upload2(String name, HttpServletRequest request) throws IllegalStateException, IOException { 55 List<String> result = new ArrayList<String>(); 56 if (request instanceof MultipartHttpServletRequest) { 57 MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request; 58 List<MultipartFile> files = multipartHttpServletRequest.getFiles("multipartFile"); 59 Iterator<MultipartFile> iterator = files.iterator(); 60 while (iterator.hasNext()) { 61 // 取出每一个文件 62 MultipartFile file = iterator.next(); 63 try { 64 // 保存上传信息 65 result.add(this.saveFile(file)); 66 } catch (Exception e) { 67 e.printStackTrace(); 68 } 69 } 70 } 71 return result; 72 } 73 74 /** 75 * 文件保存处理 76 * 77 * @param file 78 * 上传文件 79 * @return 文件保存路径 80 * @throws Exception 81 * 上传异常 82 */ 83 public String saveFile(MultipartFile multipartFile) throws Exception { 84 String filePath = "no file!!!"; 85 if (multipartFile != null && multipartFile.getSize() > 0) { 86 // 创建文件名称 87 String fileName = UUID.randomUUID() + "." 88 + multipartFile.getContentType().substring(multipartFile.getContentType().lastIndexOf("/") + 1); 89 // 获取到文件的路径信息 90 RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); 91 ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes; 92 filePath = servletRequestAttributes.getRequest().getServletContext().getRealPath("/") + fileName; 93 // 打印保存路径 94 System.out.println(filePath); 95 File saveFile = new File(filePath); 96 // 文件保存 97 multipartFile.transferTo(saveFile); 98 } 99 return filePath; 100 } 101 102 }