一、源码解读
了解源码,才能更好得学习,看多了源码,也发现自己越来越菜,难受!好了,废话不多说,下面开始学习吧。
【CommonsMultipartResolver.java】
如果有小伙伴做过关于文件上传的功能,相信对这个类绝不陌生。我先简单介绍一下它,在Servlet3.0
之前,基本上都是用它,但是这个工具虽然对版本的兼容性比较好,但是它的缺点也十分明显,需要依赖其他jar包,如下:
- common-fileupload.jar
- common-io.jar
上面这两者的jar包版本我就不做过多解释了,因为我们现在很幸福,有Maven帮助我们管理依赖的版本,有了SpringBoot之后,我们更幸福啦!因为常用的jar包,我们都不需要关系它的版本了,好像有点啰嗦,回归正题。
下面我们来看看CommonsMultipartResolver
的源码:
在网上查资料找到一篇对这个工具分析比较全面和仔细的博客,这里我分享给大家,Dispatcher的重要组件之一MultipartResolver(StandardServletMultipartResolver和CommonsMultipartResolver)的用法。
我想讲的是它所实现的实现的接口MultipartResolver
,下面打开这个接口的结构看看,都有哪些实现类,如下:
可以看到,它有两个实现类,所以这意味着我们在选择工具的时候又多了一种选择,对,就是它了StandardServletMultipartResolver
。接下来,就来了解一下为什么我们要选择它。首先,StandardServletMultipartResolver
在Servlet3.0之后就支持了,而且它不用依赖其他jar包,是不是很方便?那就有小伙伴问了,在什么环境下可以使用这个工具呢,其实从Tomcat7.0之后就支持Servlet3.0了,SpringBoot就更不用多说了,毕竟它更牛,内嵌Tomcat,所以大家可以放心的使用。接下来,我就详细介绍一下这个工具如何使用。
二、单个文件上传
开始之前,先简单说一下,单文件上传我会用Form表单和Ajax分别举例,后面多文件上传也是如此。
【方法一:Form表单】
先来完成后端代码编写,其实后端代码逻辑也比较简单。首先,先定义上传文件的目录路径,如果该目录不存在就先创建,然后,为了避免文件重名,需要给它改个名字,这里如果对上传的文件名字没有什么要求可以使用UUID等工具类来随机生成,如果上传的文件名称需要在页面显示,也可以使用MD5等可逆的加密算法先改名回显时再解密即可,最后如果需要写到硬盘上,多做一步持久化操作即可,在这里我就不做这步操作了,这里我就返回该文件的路径了。
【FileUploadController.java】
package com.mango.fileupload;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
@RestController
public class FileUploadController {
SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd/");
@PostMapping("/upload")
public String upload(MultipartFile file, HttpServletRequest request) {
//1.定义上传文件目录
String format = sdf.format(new Date());
String path = request.getServletContext().getRealPath("/img") + format;
File folder = new File(path);
if (!folder.exists()) {
folder.mkdirs();
}
//2.获取文件信息
String oldName = file.getOriginalFilename();
String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));
try {
file.transferTo(new File(folder, newName));
//3.返回上传文件的url
String url = request.getScheme() + "://" + request.