SpringMVC3️⃣请求:文件上传
回顾:Java Web文件上传
-
浏览器处理上传文件,将文件以流的形式提交到服务器端
commons-fileupload
:Apache 的文件上传组件,取代原生的文件上传流。commons-io
:commons-fileupload 组件依赖于该组件。
-
客户端表单三要素
- 提交方式:
method="post"
- 编码类型:
enctype="multipart/form-data"
- 文件表单项
- 提交方式:
SpringMVC 文件上传
- 更简单的封装
- 即插即用
1、说明
服务器端收到请求时,DispatcherServlet 的 checkMultipart()
调用 MultipartResolver 的 isMultiPart()
,判断请求中是否包含文件上传控件。
- 若请求数据中包含文件
- 调用 MultipartResolver 的
resolveMultipart()
来解析请求数据。 - 将文件数据解析成 MultipartFile,封装成 MultipartHttpServletRequest 对象。
- 传递给 Controller。
- 调用 MultipartResolver 的
- MultipartFile
- 此时这个文件存储在内存中或临时的磁盘文件中。
- 需要将其转存到一个合适的位置,因为请求结束后临时存储将被清空。
2、API
MultipartResolver 类
类似原来的 ServletFileUpload
-
isMultipart()
:对应 ServletFileUpload 类的isMultipartContent()
; -
resolveMultipart()
:对应 ServletFileUpload 类的parseRequest()
; -
cleanupMultipart()
:对应 DiskFileItem 类的delete()
;// 判断请求是否包含文件上传控件 boolean isMultipart(HttpServletRequest request); // 解析请求 MultipartHttpServletRequest resolveMultipart(HttpServletRequest request); // 清除主题内容 void cleanupMultipart(MultipartHttpServletRequest request);
MultipartFile 类
类似原来的 FileItem 类
-
getName()
-
getOriginalFilename()
-
getContentType()
// 获取参数的名称 String getName(); // 获取上传文件名 String getOriginalFilename(); // 获取文件内容的类型 String getContentType(); // 判断文件是否为空 boolean isEmpty(); // 获取文件大小 long getSize(); // 将文件内容以字节数组的形式返回 byte[] getBytes(); // 获取文件输入流:将文件内容以输入流的形式返回 InputStream getInputStream(); // 将上传文件内容保存到指定目录文件中 void transferTo(File dest);
3、使用
开发步骤
- 导入依赖
- 配置文件上传解析器
- 编写 Controller
3.1、环境搭建
-
导入
commons-fileupload
:Maven 会自动导入它的依赖包commons-io
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency>
-
配置文件上传解析器:id 必须为 multipartResolver
-
上传文件的编码类型:需与客户端页面编码格式相同
-
上传文件总大小:单位 byte
-
上传单个文件的大小:单位 byte
-
缓存文件的最大值:单位 byte
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="utf-8"/> <property name="maxUploadSize" value="10485760"/> <property name="maxUploadSizePerFile" value="1024"/> <property name="maxInMemorySize" value="40960"/> </bean>
-
3.2、单文件上传
表单
<form action="" method="post" enctype="multipart/form-data">
用户<input type="text" name="username"><br>
文件<input type="file" name="uploadFile"><br>
<input type="submit">
</form>
CommonsMultipartFile:封装请求参数中的文件。
主要步骤:
-
获取上传文件名:
getOriginalFilename()
-
设置上传文件的保存路径
-
保存文件:
transferTo()
(也可使用 IO 流传输)@RestController public class FileController { @RequestMapping("/upload") public void upload(@RequestParam("uploadFile") CommonsMultipartFile file) throws IOException { // 上传文件名 String filename = file.getOriginalFilename(); // 保存路径 File uploadPath = new File("F:\\temp"); if (!uploadPath.exists()) { uploadPath.mkdir(); } // 保存文件 file.transferTo(new File(uploadPath + "\\" + filename)); } }
3.3、多文件上传
相比单文件上传
- 将 Controller 方法参数 CommonsMultipartFile 声明为数组类型。
- 遍历数组,其它操作相同。
表单
<form action="${pageContext.request.contextPath}/uploads" method="post" enctype="multipart/form-data">
用户<input type="text" name="username"><br>
文件<input type="file" name="uploadFiles"><br>
文件<input type="file" name="uploadFiles"><br>
文件<input type="file" name="uploadFiles"><br>
<input type="submit">
</form>
CommonsMultipartFile:封装请求参数中的多个文件。
@RequestMapping("/uploads")
public void uploads(@RequestParam("uploadFiles") CommonsMultipartFile[] files) throws IOException {
for (CommonsMultipartFile file : files) {
// 上传文件名
String filename = file.getOriginalFilename();
// 保存路径
File uploadPath = new File("F:\\temp");
if (!uploadPath.exists()) {
uploadPath.mkdir();
}
// 保存文件
file.transferTo(new File(uploadPath + "\\" + filename));
}
}