MultipartFile是SpringMVC提供简化上传操作的工具类。在不使用框架之前,都是使用原生的HttpServletRequest来接收上传的数据,文件是以二进制流传递到后端的,然后需要我们自己转换为File类,
在Spring 框架中,对于文件上传下载的支持是通过MultipartFile
接口来实现的,一个MultipartFile
就表示客户端传过来的一个文件,而一个MultipartFile[]
数组,则表示客户端传过来的多个文件,这在实现多文件上传非常有用,当然了,通过该接口,你可以获取客户端传过来的文件的一些基本信息,比如文件名称、文件大小等.当然你也可以让Spring限制客户端传过来文件的大小和类型(比如图片文件png
还是文本文件txt
),但这些功能的实现配置不在本文的范围内。
文件上传
导入依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
Springboot上传文件限制,在实际项目开发中,需要对用户上传文件的大小进行限制,这样才可以保证服务器的资源不被浪费。修改application.properties配置文件,如下所示:
# 启用http上传
spring.servlet.multipart.enabled=true
# 设置支持的单个上传文件的大小限制
spring.servlet.multipart.max-file-size=10MB
# 设置最大的请求文件大小,设置总体大小请求
spring.servlet.multipart.max-request-size=20MB
# 当上传文件达到指定配置量的时候,将文件内容写入磁盘
spring.servlet.multipart.file-size-threshold=512KB
# 设置上传的临时目录
spring.servlet.multipart.location=/
对于Springboot上传文件的上传限制,也可以利用Bean实现同样的效果,实现代码,如下所示:
@Configuration
public class UploadConfig {
@Bean
public MultipartConfigElement getMultipartConfig() {
MultipartConfigFactory config = new MultipartConfigFactory();
// 设置上传文件的单个大小限制
config.setMaxRequestSize(DataSize.parse("10MB"));
// 设置总的上传的大小限制
config.setMaxRequestSize(DataSize.parse("100MB"));
// 设置临时保存目录
config.setLocation("/");
// 创建一个上传配置并返回
return config.createMultipartConfig();
}
}
单文件上传
文件上传的表单和普通表单有一点不同之处,就是需要添加enctype="multipart/form-data"
这个属性,暗指该表单存在文件上传。并且<input/>
标签的name
属性值必须和后端接口的MultipartFile
参数名一致,也就是都是file
<form action="/upload" method="POST" enctype="multipart/form-data">
<input name="file" type="file"/>
<button type="submit">上传文件</button>
</form>
/**
* 文件上传
* @param file 上传文件
* @return
*/
@PostMapping("/upload")
@ResponseBody
public String upload(MultipartFile file) {
if(file.isEmpty()){
return "文件为空";
}
System.err.println("文件的大小为 :" + file.getSize());
System.err.println("文件的媒体类型为 : " + file.getContentType());
System.err.println("文件名为: " + file.getOriginalFilename());
// 设置文件存储路径
String filePath = "C:\\Users\\YG\\Desktop\\";
String uploadFilePath = uploadFile(file, filePath);
if (!StrUtil.isBlank(uploadFilePath)){
return "上传成功: "+uploadFilePath;
}
return "上传失败";
}
/**
* 文件上传工具类
* @param file
* @param filePath
* @return
*/
private String uploadFile(MultipartFile file, String filePath){
// 获取文件名
String fileName = file.getOriginalFilename();
// 获取日期,拼接到文件名中,避免文件名重复
String today = DateUtil.today();
File newFile = new File(filePath, today + fileName);
// 检测是否存在该目录
if (!newFile.getParentFile().exists()){
newFile.getParentFile().mkdirs();
}
try {
// 写入文件
file.transferTo(newFile);
return filePath+today+fileName;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
多文件上传
原理:在单文件上传的基础上,将MultipartFile 换为数组MultipartFile [],循环遍历即可。
如果接受参数是HttpServletRequest request
<!--多文件上传-->
<form action="/uploadBatch" method="post" enctype="multipart/form-data">
<p>文件1:<input type="file" name="file"/></p>
<p>文件2:<input type="file" name="file"/></p>
<p><input type="submit" value="批量上传"/></p>
</form>
/**
* 上传多个文件
* @param request
* @return
*/
@PostMapping("/uploadBatch")
@ResponseBody
public String uploadBatch(MultipartHttpServletRequest request){
List<MultipartFile> files = request.getFiles("file");
String filePath = "C:\\Users\\YG\\Desktop\\";
for (int i = 0; i < files.size(); i++){
MultipartFile file = files.get(i);
if (!file.isEmpty()){
uploadFile(file, filePath);
System.out.println("第 "+i+" 个文件上传成功");
}else {
System.out.println("第 "+i+" 个文件上传失败");
}
}
return "上传成功";
}
上传多文件的话,需在表单的input中加入multiple="multiple"。(可一次选择多个文件)
html文件<input/>
标签的multiple
属性为multiple="multiple"
,该属性表示支持文件多选操作。同时,和单文件上传相同,我们的<input/>
标签的name
属性必须和后端的MultipartFile[]
参数名相同,即files
<form action="/download" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple="multiple" value="请选择多个文件"/>
<button type="submit">multi submit second</button>
</form>
/**
* 上传多个文件
* @param request
* @return
*/
@PostMapping("/uploadBatch")
@ResponseBody
public boolean multiFile(MultipartFile[] files) throws IllegalStateException, IOException {
if(files.length == 0) {
return false;
}
File file = null;
String filePath = "C:\\Users\\YG\\Desktop\\";
for (int i = 0; i < files.length; i++) {
System.err.println("第" + i + "个文件的大小为" + files[i].getSize());
System.err.println("第" + i + "个文件是否为空" + files[i].isEmpty());
System.err.println("第" + i + "个文件的媒体类型为" + files[i].getContentType());
System.err.println("第" + i + "个文件的文件名为" + files[i].getName());
System.err.println("第" + i + "个文件的源文件名为" + files[i].getOriginalFilename());
file = new File(path + files[i].getOriginalFilename());
files[i].transferTo(file);
}
return false;
}
上传文件夹的话,需在表单input中加入webkitdirectory directory。(仅能够选择文件夹,文件夹内的文件也能成功上传)
<form action="/upload" method="POST" enctype="multipart/form-data">
<input name="file" type="file" multiple="multiple" webkitdirectory directory/>
<button type="submit">上传文件</button>
</form>
下载文件
下载文件就是程序读取文件流,然后响应到客户端(输出流操作)
<a href="/download">下载</a>
/**
* 文件下载
* @param response
* @return
*/
@RequestMapping("/download")
@ResponseBody
public String download(HttpServletResponse response){
String fileName = "QQ.png";
if (!StrUtil.isBlank(fileName)){
//设置文件路径
File file = new File("C:\\Users\\YG\\Desktop\\QQ.png");
if (file.exists()){
// 设置强制下载不打开
response.setContentType("application/force-download");
// 设置文件名
response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
byte[] buff = new byte[1024];
BufferedInputStream bis = null;
OutputStream os = null;
try {
os = response.getOutputStream();
bis = new BufferedInputStream(new FileInputStream(file));
int i = bis.read(buff);
while (i != -1) {
os.write(buff, 0, buff.length);
os.flush();
i = bis.read(buff);
}
return "下载成功!";
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
return "下载失败!";
}