从Spring3.1开始,Spring提供了两个MultipartResolver的实现用于处理multipart请求。
Servlet3之前它只有一个基于commons-fileupload的实现CommonsMultipartResolver
文件上传,在使用时,必须要引入相应的jar包;但在Servlet3之后Spring提供了基于Servlet3的文件上传StandardServletMultipartResolver
,这种上传方式不需要引用其他jar包,但是必须使用支持Servlet3.0的容器才可以。
TomCat7.0.x之后Servlet都在3.0以上,具体比较可查看这里。
SpringBoot中默认使用第二种StandardServletMultipartResolver方式,本文案例基于这种方式演示:
1. 单文件上传(表单方式)
1.1创建上传表单
注意:
- 上传文件method必须是
post
- enctype为
multipart/form-data
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="上传">
</form>
1.2 后台上传业务处理
@RestController
public class FileUpload {
@PostMapping("/upload")
public String upload(MultipartFile file, HttpServletRequest req) {
if (file != null) {
//用于后面文件夹根据日期存放
SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd/");
//生成日期格式字符串
String format = sdf.format(new Date());
String pathDate = req.getServletContext().getRealPath("")+format;
//判断文件夹是否存在,不存在则创建
File filePath = new File(pathDate);
if (!filePath.exists()) {
filePath.mkdirs();
}
//上传的文件名
String oldName = file.getOriginalFilename();
//防止文件名重复,在这里做一些处理,生成新的文件名 uuid+oldName文件后缀
String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));
try {
//文件上传,成功后返回文件路径
file.transferTo(new File(filePath, newName));
return req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + format + newName;
} catch (IOException e) {
e.printStackTrace();
}
}
return "error";
}
}
2. ajax方式单文件上传
只需将前端改为ajax方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
<script src="jquery-1.12.4.js"></script>
</head>
<body>
<input type="file" id="file">
<input type="button" onclick="upload()" value="上传">
<div id="result"></div>
</body>
<script>
function upload() {
var sourceFile = $("#file")[0].files[0];
var formData = new FormData();
formData.append("file",sourceFile);
$.ajax({
type:'post',
url:'/upload',
data:formData,
processData: false, //不处理数据
contentType:false, //不设置类型
success:function (msg) {
$("#result").html(msg);
}
})
}
</script>
</html>
3. 多文件上传
1. 在input类型为file标签内添加 multiple即可实现多文件选中上传
2. 也可以编写多个input文件上传,后台数据接收多写几个MultipartFile
<form action="/uploads" method="post" enctype="multipart/form-data">
<!-- 在input类型为file标签内添加 multiple即可实现多文件选中上传-->
<!-- 也可以编写多个input文件上传,后台数据接收多写几个MultipartFile -->
<input type="file" name="files" multiple>
<input type="submit" value="上传">
</form>
后端处理:
@PostMapping("/uploads")
//使用MultipartFile[]接收多个文件
public String uploads(MultipartFile[] files, HttpServletRequest req) {
if (files != null&&files.length>0) {
//用于后面文件夹根据日期存放
SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd/");
//生成日期格式字符串
String format = sdf.format(new Date());
String pathDate = req.getServletContext().getRealPath("")+format;
//判断文件夹是否存在,不存在则创建
File filePath = new File(pathDate);
if (!filePath.exists()) {
filePath.mkdirs();
}
for (MultipartFile file : files) {
//上传的文件名
String oldName = file.getOriginalFilename();
//防止文件名重复,在这里做一些处理,生成新的文件名 uuid+oldName文件后缀
String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));
try {
//文件上传,成功后返回文件路径
file.transferTo(new File(filePath, newName));
System.out.println(req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + format + newName);
} catch (IOException e) {
e.printStackTrace();
}
}
return "success";
}
return "error";
}