目录
[(1)传统 Servlet](#(1)传统 Servlet)
[2.Spring MVC的方式](#2.Spring MVC的方式)
[(2)导入依赖,因为 是原生tomcat自带的,所以只需导入这个tomcat的包](#(2)导入依赖,因为 是原生tomcat自带的,所以只需导入这个tomcat的包)
(4)配置好tomcat,打开页面上传并提交文件,观察本地是否接收到了文件
[3.Spring MVC的方式](#3.Spring MVC的方式)
(5)配置springmvc.xml,视图解析器和文件上传配置
一、Java文件的三种上传方式
(一)本质区别
1.Servlet
(1)传统 Servlet
·依赖第三方jar包:commons-fileupload+commons-io/
·核心是手动解析请求流,通过ServletFileUpload把请求拆成FileItem,再遍历判断文件
·步骤多、代码繁琐、需要手动处理临时文件、内存阈值、文件名等细节
·用途:Servlet老项目写法,现在也用来理解底层
(2)原生Servlet3.0
·不用额外框架和jar包,serlet3.0自带支持
·用@MultipartConfig注解开启文件上传,通过requesat.getPart()直接获取文件
·代码简洁,不用手动解析请求流,服务器底层帮你处理了拆分、临时文件等逻辑
·用途:原生JavaWeb项目文件上传,比传统commons方式更现代、更简洁
2.传统SpringMVC
·基于SpringMVC+依赖 commons-fileupload第三方包
·强转MultipartHttpServletRequest拿文件
·配置麻烦、写法老旧
·用途:也算是淘汰了
3.MultipartFile上传
·Spring MVC/Spring Boot 官方封装好的标准写法
·直接在形参写MultipartFile接收,不同手动解析流
·配置简单、代码极简、支持单/多文件
·用途;现在所有企业、SpringMVCw/MavenWeb/SpringBoot统一用这个
(二)核心对比
|---------------|--------------------------|--------------|-------------|----------------|
| 方式 | 依赖 | 代码难度 | 配置量 | 实际开发使用 |
| 原生 Servlet | 仅 Servlet | 难、代码多 | 少 | 不用 |
| 传统 SpringMVC | 必须 commons-fileupload | 中等 | 多(需配解析器) | 淘汰 |
| MultipartFile | SpringMVC 核心 + commons 包 | 简单、极简 | 少 | 主流必用 |
(三)具体代码实现
1.传统Servlet
(1)目录

(2)pom.xml导入依赖
XML
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<!-- 统一版本号 -->
<commons-io.version>2.11.0</commons-io.version>
<commons-fileupload.version>1.4</commons-fileupload.version>
<commons-codec.version>1.15</commons-codec.version>
</properties>
<!-- ✅ 正确的 Servlet 2.5 依赖(必须加 provided)-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<!-- 文件上传核心依赖 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
</dependencies>
(3)编写测试页面index.jsp
html
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2><%= "Hello World!" %></h2>
<!-- 关键:必须加 enctype="multipart/form-data",文件编码的形式 -->
<form action="/updateFile" method="post" enctype="multipart/form-data">
文件上传演示案例: <input type="file" name="file">
<br/>
提交按钮: <input type="submit" value="提交文件">
</form>
</body>
</html>
(4)编写FileServlet
java
package com.qcby.servlet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
req.setCharacterEncoding("UTF-8");
// 1. 判断是否是文件上传
if (!ServletFileUpload.isMultipartContent(req)) {
resp.getWriter().write("错误:表单不是文件上传类型!");
return;
}
try {
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> fileItems = upload.parseRequest(req);
for (FileItem item : fileItems) {
// 文件字段
if (!item.isFormField() && "file".equals(item.getFieldName())) {
String originalFilename = item.getName();
// 截取后缀
String ext = originalFilename.substring(originalFilename.lastIndexOf("."));
String newFileName = UUID.randomUUID() + ext;
// 上传目录
File uploadDir = new File("D:/upload");
if (!uploadDir.exists()) {
uploadDir.mkdirs();
}
File saveFile = new File(uploadDir, newFileName);
item.write(saveFile);
System.out.println("上传成功:" + saveFile.getAbsolutePath());
resp.getWriter().write("文件上传成功!");
}
}
} catch (Exception e) {
e.printStackTrace();
resp.getWriter().write("上传失败:" + e.getMessage());
}
}
}
客户端以 post 方式 + enctype="multipart/form-data"** 提交文件表单
↓
请求进入 Servlet 后先设置编码
↓
通过ServletFileUpload判断是否为文件上传类型
↓
用磁盘工厂创建上传解析器,把请求解析成FileItem集合
↓
遍历判断出是文件类型且表单项 name 匹配
↓
截取文件后缀并用 UUID 生成新文件名,自动创建本地存放目录
↓
最后将文件写入磁盘保存,并给前端返回上传结果。

(5)编写web.xml
XML
<?xml version="1.0" encoding="UTF-8"?>
<web-app
version="4.0"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:javaee="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">
<servlet>
<servlet-name>fileServlet</servlet-name>
<servlet-class>com.qcby.servlet.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>fileServlet</servlet-name>
<url-pattern>/updateFile</url-pattern>
</servlet-mapping>
</web-app>
(6)配置tomcat后运行,上传文件

(7)点击提交后,查看本地文件夹是否有文件上传

2.Spring MVC的方式
(1)编写pom.xml,导入依赖
XML
<properties>
<!-- 统一版本号 -->
<commons-io.version>2.11.0</commons-io.version>
<commons-fileupload.version>1.4</commons-fileupload.version>
<commons-codec.version>1.15</commons-codec.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
2.原生Servlet3.0
(1)目录

(2)导入依赖,因为 是原生tomcat自带的,所以只需导入这个tomcat的包
XML
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>9.0.75</version>
</dependency>
(3)编写测试页面index.jsp
html
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传测试</title>
</head>
<body>
<h3>单文件上传</h3>
<form action="upload30" method="post" enctype="multipart/form-data">
<input type="file" name="file"/>
<button type="submit">上传</button>
</form>
</body>
</html>
(4)配置好tomcat,打开页面上传并提交文件,观察本地是否接收到了文件
3.Spring MVC的方式
(1)目录

(2)导入依赖
XML
<properties>
<!-- 统一版本号 -->
<commons-io.version>2.11.0</commons-io.version>
<commons-fileupload.version>1.4</commons-fileupload.version>
<commons-codec.version>1.15</commons-codec.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
(3)编写index.jsp
html
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2><%= "Hello World!" %></h2>
<!-- 关键:必须加 enctype="multipart/form-data",文件编码的形式 -->
<form action="/updateFile" method="post" enctype="multipart/form-data">
文件上传演示案例: <input type="file" name="file">
<br/>
提交按钮: <input type="submit" value="提交文件">
</form>
</body>
</html>
(4)suc.jsp
html
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>上传文件入门案例MVC</title>
</head>
<body>
<h1>文件上传成功!</h1>
</body>
</html>
(5)配置springmvc.xml,视图解析器和文件上传配置
XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.qcby"></context:component-scan>
<!--配置视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--后台mvc关于文件上传的配置-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxInMemorySize" value="10240000"/>
</bean>
</beans>
(6)FileController
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 FileController {
@RequestMapping("/updateFile")
// public String uploadFile(MultipartFile file) throws IOException {
public String uploadFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("成功");
//转换request
MultipartHttpServletRequest mr=(MultipartHttpServletRequest) request;
//获得存储文件的map
Map<String, MultipartFile> fileMap = mr.getFileMap();
//获得文件
MultipartFile pic = fileMap.get("file");
// 创建该文件夹
File file1 = new File("D:/Aupload01");
// 判断该文件夹是否存在
if(!file1.exists()){
// 创建文件夹
file1.mkdirs();
}
// 获取到上传文件的名称
String filename = pic.getOriginalFilename();
// 把文件的名称修改成为一的值 sdfs-csdf-fwer-sdfw
String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
// 唯一的值
filename = uuid+"_"+filename;
System.out.println("文件名称:"+filename);
// 上传文件
pic.transferTo(new File(file1,filename));
return "suc";
}
}
(7)web.xml
XML
<?xml version="1.0" encoding="UTF-8"?>
<web-app
version="4.0"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:javaee="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">
<display-name>Archetype Created Web Application</display-name>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--配置加载springmvc配置文件加载-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--启动加载-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
(8)上传提交文件,观察是否收到上传的文件
4.Multipart的方式
(1)目录

(2)导入依赖
XML
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>5.3.20</spring.version>
</properties>
<dependencies>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 文件上传核心依赖(Spring MVC Multipart 必须) -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
(3)index.jsp测试页面
html
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传测试</title>
</head>
<body>
<h3>单文件上传</h3>
<form action="/file/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file"/><br>
<button type="submit">上传</button>
</form>
</body>
</html>
(4)springmvc.xml
XML
<!-- 开启注解扫描 -->
<context:component-scan base-package="com.qcby"/>
<!-- 开启Spring MVC注解驱动 -->
<mvc:annotation-driven/>
<!-- 文件上传解析器:MultipartFile 必须依赖这个 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 编码 -->
<property name="defaultEncoding" value="UTF-8"/>
<!-- 单个文件最大 10MB -->
<property name="maxUploadSize" value="10485760"/>
<!-- 总请求最大 50MB -->
<property name="maxUploadSizePerFile" value="10485760"/>
</bean>
(5)FileUploadController
java
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
@Controller
@RequestMapping("/file")
public class FileUploadController {
@PostMapping("/upload")
@ResponseBody
public String upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
// 1. 判断文件是否为空
if (file.isEmpty()) {
return "上传失败:文件为空";
}
// 2. 获取上传目录(项目外的路径,避免部署后丢失)
String uploadPath = "D:/MultipartUpload/";
File dir = new File(uploadPath);
if (!dir.exists()) {
dir.mkdirs();
}
// 3. 生成唯一文件名,防止重名覆盖
String originalName = file.getOriginalFilename();
String suffix = originalName.substring(originalName.lastIndexOf("."));
String newFileName = UUID.randomUUID().toString() + suffix;
// 4. 保存文件
try {
file.transferTo(new File(uploadPath + newFileName));
return "success!:" + uploadPath + newFileName;
} catch (IOException e) {
e.printStackTrace();
return "上传失败:" + e.getMessage();
}
}
}
(6)web.xml
XML
<!-- Spring MVC 前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 字符编码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(7)上传并提交文件之后观察是否收到了文件
5.大文件拆分的方式
(1)目录

(2)导入依赖
XML
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- 文件上传依赖 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.33</version>
</dependency>
</dependencies>
(3)index.jsp
html
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>大文件分片上传</title>
</head>
<body>
<h2>大文件分片上传(纯 Servlet 版)</h2>
<input type="file" id="fileInput"/>
<button onclick="upload()">开始上传</button>
<div id="progress"></div>
<script>
const CHUNK_SIZE = 5 * 1024 * 1024; // 5MB
async function upload() {
const file = document.getElementById('fileInput').files[0];
if (!file) {
alert('请选择文件');
return;
}
const fileName = file.name;
const totalChunks = Math.ceil(file.size / CHUNK_SIZE);
let uploaded = 0;
// 上传分片
for (let i = 0; i < totalChunks; i++) {
const start = i * CHUNK_SIZE;
const end = Math.min(start + CHUNK_SIZE, file.size);
const chunk = file.slice(start, end);
let formData = new FormData();
formData.append("file", chunk);
formData.append("fileName", fileName);
formData.append("chunkIndex", i);
try {
let res = await fetch("/uploadChunk", {
method: "POST",
body: formData
});
let text = await res.text();
console.log(text);
} catch (e) {
console.log("上传失败", e);
alert("上传分片失败");
return;
}
uploaded++;
document.getElementById("progress").innerText = "已上传:" + uploaded + "/" + totalChunks;
}
alert("所有分片上传完毕,开始合并......");
// ↓↓↓ 这里是关键!必须走合并!
try {
let res = await fetch("/merge?fileName=" + encodeURIComponent(fileName), {
method: "POST"
});
let text = await res.text();
alert("合并结果:" + text);
} catch (e) {
console.log("合并失败", e);
alert("合并失败");
}
}
</script>
</body>
</html>
(4)ChunkUploadServlet
java
package com.qcby.servlet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
@WebServlet("/uploadChunk")
public class ChunkUploadServlet extends HttpServlet {
private static final String TEMP_DIR = "D:/upload/temp/";
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
request.setCharacterEncoding("UTF-8");
if (!ServletFileUpload.isMultipartContent(request)) {
response.getWriter().write("error: 不是文件上传请求");
return;
}
try {
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = upload.parseRequest(request);
String fileName = null;
int chunkIndex = 0;
// 修正:类型改为 FileItem
FileItem chunkFile = null;
for (FileItem item : items) {
if (item.isFormField()) {
String fieldName = item.getFieldName();
if ("fileName".equals(fieldName)) {
fileName = item.getString("UTF-8");
} else if ("chunkIndex".equals(fieldName)) {
chunkIndex = Integer.parseInt(item.getString("UTF-8"));
}
} else {
// 这里赋值就不会报红了
chunkFile = item;
}
}
if (fileName == null || chunkFile == null) {
response.getWriter().write("error: 参数不全");
return;
}
// 2. 为每个文件创建临时目录
File tempDir = new File(TEMP_DIR + fileName + "/");
if (!tempDir.exists()) {
tempDir.mkdirs();
}
// 3. 保存分片
File chunk = new File(tempDir, chunkIndex + ".part");
chunkFile.write(chunk);
response.getWriter().write("success: 分片" + chunkIndex + "上传完成");
} catch (Exception e) {
e.printStackTrace();
response.getWriter().write("error: " + e.getMessage());
}
}
}
(5)MergeServlet
java
package com.qcby.servlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Arrays;
@WebServlet("/merge")
public class MergeServlet extends HttpServlet {
private static final String TEMP_DIR = "D:/upload/temp/";
private static final String FINAL_DIR = "D:/upload/final/";
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=UTF-8");
request.setCharacterEncoding("UTF-8");
String fileName = request.getParameter("fileName");
if (fileName == null || fileName.isEmpty()) {
response.getWriter().write("文件名不能为空");
return;
}
File tempDir = new File(TEMP_DIR + fileName + "/");
if (!tempDir.exists()) {
response.getWriter().write("分片不存在");
return;
}
File[] chunks = tempDir.listFiles();
if (chunks == null || chunks.length == 0) {
response.getWriter().write("没有分片");
return;
}
// 排序
Arrays.sort(chunks, (a, b) -> {
int i1 = Integer.parseInt(a.getName().replace(".part", ""));
int i2 = Integer.parseInt(b.getName().replace(".part", ""));
return Integer.compare(i1, i2);
});
// 自动创建 final 文件夹
File finalDir = new File(FINAL_DIR);
if (!finalDir.exists()) {
finalDir.mkdirs();
}
File finalFile = new File(FINAL_DIR + fileName);
// 合并
try (FileOutputStream fos = new FileOutputStream(finalFile);
BufferedOutputStream bos = new BufferedOutputStream(fos)) {
byte[] buffer = new byte[1024 * 1024];
for (File chunk : chunks) {
try (FileInputStream fis = new FileInputStream(chunk);
BufferedInputStream bis = new BufferedInputStream(fis)) {
int len;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
}
chunk.delete();
}
}
tempDir.delete();
response.getWriter().write("合并成功!文件路径:" + finalFile.getAbsolutePath());
}
}