SpringBoot实现MultipartFile文件上传

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接收到此请求信息后,如果有上传文件存在,则会直接返回上传信息(开发者也可以根据情况选择将文件保存)。

SpringBoot实现MultipartFile文件上传

演示效果,如下所示:

SpringBoot实现MultipartFile文件上传

SpringBoot实现MultipartFile文件上传

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 }