SpringMVC—上传文件

一.SpringMVC的文件上传功能

Spring MVC 为文件上传提供了直接的支持,这种支持是通过即插即用的 MultipartResolver 实现的,MultipartResolver 是SpringMVC九大组件之一。Spring 用 Jakarta Commons FileUpload 技术实现了一个MultipartResolver实现类:CommonsMultipartResovler

二.配置

Spring MVC 上下文中默认没有装配 MultipartResovler,因此默认情况下不能处理文件的上传工作,如果想使用 Spring 的文件上传功能,需现在上下文中配置 MultipartResolver,并且配置的bean的id必须是multipartResolver,因为这个组件在初始化时是按照id去IOC容器中查找的。九大组件有些是按id查找,有些是按class查找。

1
2
3
4
5
6
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<property name="maxUploadSize" value="40960"></property>
<property name="maxInMemorySize" value="4096"></property>
<property name="resolveLazily" value="true"></property>
</bean>

三.示例

前端通过form表单的形式提交参数

1
2
3
4
5
<form action="file/upload" method="post" enctype="multipart/form-data">
<input type="text" name="description"/>
<input type="file" name="uploadFile">
<input type="submit" value="上传">
</form>

在controller中写一个文件上传的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@RequestMapping("/file/upload")
public String upload(@RequestParam("description")String desc,
@RequestParam("uploadFile")MultipartFile uploadFile) {


System.out.println(desc);

String path = "D:/FFOutput";
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}

try {
//getOriginalFilename():获取上传的文件的原文件名(文件名.后缀)
//transerTo():调用这个方法可以直接将文件上传至指定文件
uploadFile.transferTo(new File(path + File.separator + uploadFile.getOriginalFilename()));
} catch (IllegalStateException | IOException e) {
e.printStackTrace();
}
return "success";

}

除了使用@RequestParam,也可以通过bean的方式接受参数:

1
2
3
4
@RequestMapping(value = "/file/upload")
public Response upload(FileUploadRequest request) {
//...
}
1
2
3
4
5
6
7
8
9
10
11
12

public class FileUploadRequest implements Serializable {

private static final long serialVersionUID = 1L;

private String description;

private MultipartFile file;

//...

}

如果上传多个文件,则用 MultipartFIle 数组来接收上传的文件。

1
2
3
4
5
6
7
8
9
10

<form action="/file/upload2" method="post" enctype="multipart/form-data">
描述:<input type="text" name="description"/>
<input type="file" name="uploadFile">
<input type="file" name="uploadFile">
<input type="file" name="uploadFile">
<input type="file" name="uploadFile">
<input type="submit" value="上传">

</form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@RequestMapping("/file/upload2")
public String upload2(@RequestParam("description")String desc,
@RequestParam("uploadFile")MultipartFile[] uploadFiles) {

System.out.println(desc);

String path = "D:/FFOutput2";
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}

try {
if (uploadFiles != null) {
for (MultipartFile multipartFile : uploadFiles) {
multipartFile.transferTo(new File(path + File.separator
+ UUID.randomUUID().toString() + "_" + multipartFile.getOriginalFilename()));
}
}
} catch (IllegalStateException | IOException e) {
e.printStackTrace();
}
return "success";

}

配置

SpringBoot中对上传文件的大小是有限制的的,默认最大为1MB,具体可以从MultipartProperties这个类可以查到,这个类中除了文件大小限制的配置项,还包括其他和文件操作相关的配置,以SpringBoot 2.0.5 RELEASE 版本为例,源代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@ConfigurationProperties(prefix = "spring.servlet.multipart", ignoreUnknownFields = false)
public class MultipartProperties {

/**
* Whether to enable support of multipart uploads.
*/
private boolean enabled = true;

/**
* Intermediate location of uploaded files.
*/
private String location;

/**
* Max file size. Values can use the suffixes "MB" or "KB" to indicate megabytes or
* kilobytes, respectively.
*/
private String maxFileSize = "1MB";

/**
* Max request size. Values can use the suffixes "MB" or "KB" to indicate megabytes or
* kilobytes, respectively.
*/
private String maxRequestSize = "10MB";

/**
* Threshold after which files are written to disk. Values can use the suffixes "MB"
* or "KB" to indicate megabytes or kilobytes, respectively.
*/
private String fileSizeThreshold = "0";

/**
* Whether to resolve the multipart request lazily at the time of file or parameter
* access.
*/
private boolean resolveLazily = false;

//省略......

如果超过1MB,会抛出如下异常。

1
Spring Boot:The field file exceeds its maximum permitted size of 1048576 bytes.

解决办法就是配置相关参数:

1
2
3
4
5
spring:
servlet:
multipart:
max-file-size: 15MB #表示单个文件的大小限制
max-request-size: 30MB #表示单个请求文件大小的限制,一个请求中可能会上传多个文件

注意,在 SpringBoot 1.4 和 SpringBoot 1.5 的版本中是这样配置的:

1
2
3
4
spring:
http:
multipart:
max-file-size: 15Mb

具体查看MultipartProperties这个类就知道了。

------ 本文完 ------