前言
本文为 【SpringMVC教程】文件上传 相关知识,使用MultipartFile处理文件,案例例子是多文件上传,并同时返回文件上传路径与文件全路径。
📌博主主页:一个肥鲇鱼
👉开发中的坏习惯:程序员的坏习惯,你占了几个!
👉感受 Lambda 之美:体验一下Lambda之美吧,优雅编程
文件上传是项目开发中最常见的功能之一 ,SpringMVC 可以很好的支持文件上传,MultipartFile是springMVC的jar包,不需要其它坐标,可以直接使用。
🍀前端要求:上传文件,必须将表单的method
设置为POST
,并将enctype
设置为multipart/form-data
。只有在这样的情况下,浏览器才会把文件以二进制数据发送给服务器。
<form action="" enctype="multipart/form-data" method="post">
<input type="file" name="file"/>
<input type="submit">
</form>
🍀表单中enctype属性的详细说明:
- application/x-www=form-urlencoded:默认方式,只处理表单域中的 value 属性值,采用这种编码方式的表单会将表单域中的值处理成 URL 编码方式。
- multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数中,不会对字符编码。
- text/plain:除了把空格转换为 “+” 号外,其他字符都不做编码处理,这种方式适用直接通过表单发送邮件。
🍀MultipartFile 的常用方法:
String getOriginalFilename()
:获取上传文件的原名InputStream getInputStream()
:获取文件流void transferTo(File dest)
:将上传文件保存到一个目录文件中
🍀编写上传文件ServiceImpl层
/**
* 上传文件
*
* @param fileList
* @return
* @throws IOException
*/
public Map<String, String> uploadFile(List<MultipartFile> fileList) throws IOException {
// 创建目录&&上传文件
String dir = getDir(fileList);
// 拼接http路径
String path = spellPath(Arrays.asList(dir.split(",")));
HashMap<String, String> map = new HashMap<>(2);
// 回显路径
map.put("path", path); // http://127.0.0.1/pics/2022/12/09/6a45901206c649dcb310b00.png
// 文件路径
map.put("fileName", dir); // 2022/12/09/6a45901206c649dcb310b00.png
return map;
}
🍀创建文件&&上传文件
创建目录为年月日,按日期保存文件
/**
* 创建目录&&上传文件
*
* @return 上传后的文件路径
*/
public String getDir(List<MultipartFile> fileList) throws IOException {
// 判断文件集合是否为空
if (CollectionUtils.isEmpty(fileList)) {
throw new BizException("文件为空");
}
// checkFile校验文件是否符合要求
fileList.forEach(f -> this.checkFile(f));
StringBuilder files = new StringBuilder();
for (int i = 0, num = fileList.size(); i < num; i++) {
MultipartFile file = fileList.get(i);
// 年-月-日 文件夹路径 (File.separator)
String dir = new SimpleDateFormat("yyyy/MM/dd").format(new Date()) "/";
String path = FilePathConst.uploadPath + File.separator + dir;
File exist = new File(path);
// 创建文件夹
if (!exist.exists()) {
exist.mkdirs();
}
// UUID生成新的文件名
String newName = UUID.randomUUID().toString().replaceAll("-", "");
// 获取文件后缀
String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
// 采用file.transferTo来保存上传的文件
file.transferTo(new File(path + newName + suffix));
files.append(dir).append(newName).append(suffix).append(",");
}
return files.toString();
}
🍀checkFile校验文件方法
/**
* 允许上传文件类型
*/
private final List<String> fileType =
Arrays.asList(".jpg", ".jpeg", ".png", ".doc", ".docx", ".xls", ".xlsx");
/**
* 检验文件
*
* @param file
*/
private void checkFile(MultipartFile file) {
if (file.isEmpty()) {
throw new BizException("文件为空");
}
// 获取文件名
String fileName = file.getOriginalFilename();
// 获取文件后缀
String suffixName = fileName.substring(fileName.lastIndexOf("."));
// 验证后缀是否允许上传
if (!fileType.contains(suffixName)) {
throw new BizException("非法的文件,不允许的文件类型:" + suffixName);
}
// 文件大于700KB不允许上传
long size = file.getSize() / 1024;
if (size > 700) {
throw new BizException(file.getOriginalFilename() + "文件过大");
}
}
🍀spellPath拼接文件路径方法
/**
* 拼接文件路径
*
* @param str
* @return
*/
public String spellPath(List<String> str) {
StringBuilder path = new StringBuilder();
str.stream().forEach(s -> path.append("http://127.0.0.1/pics").append(s).append(','));
return path.toString();
}
🍀测试上传文件
🍀编写Controller层
/**
* 上传文件
*
* @param fileList 文件
* @return
* @throws IOException
*/
@PostMapping(value = "/uploadFile", produces = MediaType.APPLICATION_JSON_VALUE)
public Map<String, String> uploadFile(@RequestParam(value = "file") List<MultipartFile> fileList) throws IOException {
return uploadService.uploadFile(fileList);
}
{
"code": "200",
"msg": "操作成功",
"data": {
"path": "http://127.0.0.1:8080/pics/2022/12/09/e2510c6dee914b65870293963da26676.png,",
"fileName": "2022/12/09/e2510c6dee914b65870293963da26676.png,"
}
}