上篇我们学完了Servlet2.5传统上传 、Servlet3.0原生无依赖上传 ;下篇则讲解SpringMVC两种主流文件上传写法。 Java Web 四种文件上传方式(上篇)-CSDN博客
环境:JDK8 + Tomcat8.5 + SpringMVC + Maven
三、SpringMVC文件上传方式一:形参直接接收 MultipartFile
1. 简介
SpringMVC 对原生文件上传做了封装,不用手动解析请求、遍历 FileItem和操作 Part。
要点:
- 必须在
springmvc.xml配置 文件上传解析器multipartResolver - 控制器方法直接用 MultipartFile 形参接收,参数名和表单
name一致 - 自动封装上传文件、自动处理请求转码,只需要做:重命名 + 保存
- 依然要求表单加:
enctype="multipart/form-data"
2. 必须的 Maven 依赖
XML
<!-- SpringMVC核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!-- servlet依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<!-- 文件上传基础包 SpringMVC底层依赖这两个 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
3. SpringMVC 配置文件 springmvc.xml 重点配置
必须配置 multipartResolver,id 不能改 固定写法:
XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 包扫描 -->
<context:component-scan base-package="com.qcby.controller"/>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 必须配置:SpringMVC文件上传解析器 id固定为multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 编码格式 -->
<property name="defaultEncoding" value="UTF-8"/>
<!-- 单个文件最大大小 10M -->
<property name="maxUploadSizePerFile" value="10485760"/>
</bean>
<!-- 开启注解驱动 -->
<mvc:annotation-driven/>
</beans>
4. 上传表单 jsp
XML
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>SpringMVC文件上传方式一</title>
</head>
<body>
<form action="/uploadFile1" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="file"><br>
<input type="submit" value="SpringMVC上传">
</form>
</body>
</html>
5. 控制器完整代码
java
package com.qcby.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
@Controller
public class FileUploadController1 {
@RequestMapping("/uploadFile1")
public String uploadFile(MultipartFile file) throws IOException {
// 1. 判断是否为空文件
if (file.isEmpty()) {
System.out.println("未选择文件或文件为空");
return "error";
}
// 2. 获取原始文件名
String originalFilename = file.getOriginalFilename();
// 3. 截取文件后缀
String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
// 4. UUID生成唯一文件名 防止重名覆盖
String newFileName = UUID.randomUUID().toString().replace("-", "") + suffix;
// 5. 定义保存路径 不存在自动创建文件夹
File saveDir = new File("D:/AuploadMVC1");
if (!saveDir.exists()) {
saveDir.mkdirs();
}
// 6. 执行文件保存
File destFile = new File(saveDir, newFileName);
file.transferTo(destFile);
System.out.println("SpringMVC方式一上传成功:" + destFile.getAbsolutePath());
return "suc";
}
}
方式一特点
- 最简,企业开发最常用
- 直接形参接收 MultipartFile,代码少
- 配置 multipartResolver 解析器
- 参数名和表单 file 的 name 必须一致
四、SpringMVC文件上传方式二:强转 MultipartHttpServletRequest
1. 简介
原理:把原生 HttpServletRequest 强转为 MultipartHttpServletRequest,再通过 getFileMap() 获取所有上传文件,再根据 name 取出对应文件。
适用场景:需要一次性接收多个文件、或者手动管理请求对象时使用,底层和方式一本质一样,只是接收写法不同。
2. 依赖 & springmvc.xml
和上面方式一一样,不用重复改配置。
3. 上传表单 jsp
XML
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>SpringMVC文件上传方式二</title>
</head>
<body>
<form action="/uploadFile2" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="file"><br>
<input type="submit" value="上传提交">
</form>
</body>
</html>
4. 控制器完整代码
java
package com.qcby.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.UUID;
@Controller
public class FileUploadController2 {
@RequestMapping("/uploadFile2")
public String uploadFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("进入SpringMVC上传方式二");
// 1. 把原生request强转为多部件上传请求
MultipartHttpServletRequest mr = (MultipartHttpServletRequest) request;
// 2. 获取所有上传文件Map集合
Map<String, MultipartFile> fileMap = mr.getFileMap();
// 3. 根据表单name获取文件
MultipartFile pic = fileMap.get("file");
// 4. 判断文件是否为空
if (pic.isEmpty()) {
System.out.println("未选择文件或文件为空");
return "error";
}
// 5. 获取原始文件名
String filename = pic.getOriginalFilename();
// 6. UUID重构唯一文件名
String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
filename = uuid + "_" + filename;
// 7. 构建保存目录 自动创建
File file1 = new File("D:/AuploadMVC2");
if (!file1.exists()) {
file1.mkdirs();
}
// 8. 保存文件
pic.transferTo(new File(file1, filename));
System.out.println("SpringMVC方式二上传成功:" + filename);
return "suc";
}
}
方式二特点
- 手动强转 Request,更贴近底层
- 可以一次性获取多个文件,适合多文件上传
- 同样依赖
multipartResolver配置 - 代码比方式一稍多,适合学习底层原理
五、四种文件上传
1. 四种方式归类
- Servlet2.5 传统上传:依赖 commons 包,代码繁琐,老项目遗留
- Servlet3.0 原生上传 :无需第三方依赖,
@MultipartConfig + getPart() - SpringMVC 方式一 :直接形参
MultipartFile,最简 - SpringMVC 方式二 :强转
MultipartHttpServletRequest,适合多文件、底层理解
2. 共同点
- 文件上传表单必须加 :
enctype="multipart/form-data" - 都要UUID / 时间戳重命名,防止同名文件覆盖
- 都要手动判断保存目录是否存在,不存在则创建
- SpringMVC 必须配置
multipartResolver上传解析器