一、文件上传的介绍
1.文件上传的实质:文件的拷贝
文件上传:从本地将文件拷贝到服务器磁盘上
- 客户端:需要编写文件上传表单
- 服务端:需要编写代码接收上传的文件
二、客户端编码
1.文件上传三要素
- 表单的提交方式:post(get方式提交数据有大小限制)
- 表达的enctype属性值:必须设置为 multipart/form-data
multipart/form-data:多部件文件上传,指表单数据有多部分构成。 既可以有文本数据,也可以有文件等二进制数据。 - 表单中必须有文件上传项:file,必须有name属性和值
注意:默认情况下,表单的enctype的值是application/x-www-form-urlencoded,不能用于文件上传,只有使用了multipart/form-data,才能完整的传递文件数据
2.代码实例
<%--
Created by IntelliJ IDEA.
User: ASUS
Date: 2021/9/14
Time: 15:20
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>浏览器文件上传</title>
</head>
<body>
<%--
客户端实现文件上传的三要素
1.请求方式是post,因为get方式对文本内容长度有限制
2.enctype属性的值必须是multipart/form-data
multipart/form-data是多部件文件上传,指表单中可以有多个部分组成,
既可以有文本数据,也可以有文件等二进制数据
3.表单中的表单项必须有文件上传项:file,必须有name属性和值
--%>
<form method="post" enctype="multipart/form-data" action="${pageContext.request.contextPath}/upload">
<input type="file" name="upload"><br>
<input type="text" name="name"><br>
<input type="text" name="password"><br>
<input type="submit" value="文件上传">
</form>
</body>
</html>
三、服务器端编码
1.上传文件,抓包分析
2.FileUpload工具类
(1)导入依赖
FileUpload包可以很容易地将文件上传到你的Web应用程序.
IOUtils封装了Java中io的常见操作,使用十分方便 ,需要下载 commons-io-1.4.jar 包 .
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
</dependency>
(2)FileUpload核心类介绍
类名 | 介绍 |
---|---|
DiskFileItemFactory | 磁盘文件项工厂, 读取文件时相关的配置,比如: 缓存的大小 , 临时目录的位置 |
ServletFileUplaod | 文件上传的一个核心类 |
FileItem | 代表每一个表单项 |
(3)API介绍
- ServletFileUpload
方法 | 说明 |
---|---|
isMultipartContent(request) | 判断是否是一个多部件文件上传的表单 |
parseRequest(request) | 解析request获得表单项的集合 |
setHeaderEncoding(“UTF-8”) | 设置上传的文件名的编码方式 |
- FileItem
方法 | 说明 |
---|---|
isFormField() | 判断是否是普通表单项 |
getFieldName() | 获得表单的name属性值 |
getString() | 获得表单的value值 |
getName() | 获得上传文件的名称 |
getInputStream() | 获得上传文件的输入流 |
delete() | 删除临时文件 |
(4)服务器端文件上传编码
package cn.xuguowen.web.servlet;
import cn.xuguowen.utils.UUIDUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;
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.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;
/**
* @author 徐国文
* @create 2021-09-14 15:33
* 服务器端要接收客户端上传的表单数据
* 但是当前表单中有普通的表达项,也有文件表单项。
* 解决方式:使用第三方库FileUpload工具类进行文件的上传,保存到服务器端本地磁盘中
* 本次项目部署在我个人pc上,所以就是保存到我pc的磁盘中
* 使用FileUpload工具类之前,要先导入jar包/依赖坐标
*/
@WebServlet("/upload")
public class FileUploadServlet extends HttpServlet {
/**
* 使用FileUpload工具类完成文件的上传
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
// 1.创建磁盘文件工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
// 2.创建文件上传类的对象
ServletFileUpload upload = new ServletFileUpload(factory);
// 2.1设置文件上传的编码
upload.setHeaderEncoding("utf-8");
// 2.2判断表单是否是多部件文件上传的表单
boolean multipartContent = upload.isMultipartContent(req);
System.out.println("表单是否是多部件文件上传表单" + multipartContent);
// 2.3如果是多部件文件上传表单
if (multipartContent) {
// 3.开始解析请求,获取多部件文件上传表单的集合,集合中存储的是每一个表单项
List<FileItem> list = upload.parseRequest(req);
if (null != list) {
// 4.遍历多不见文件上传表单项集合
for (FileItem item : list) {
// 5.判断是普通表单项还是文件上传表单项
boolean formField = item.isFormField(); // 该方法判断是否是普通表单项
if (formField) {
// 普通表单项, 当 enctype="multipart/form-data"时, request的getParameter()方法 无法获取参数
String fieldName = item.getFieldName(); // 获取表单文本框中name的属性值
String value = item.getString("utf-8"); // 获取utf-8编码之后表单文本框中的内容
System.out.println(fieldName + " = " + value);
} else {
// 文件上传表单项
String fileName = item.getName(); // 获取文件名
// 要避免客户端上传的文件名出现重名情况,所以使用uuid工具类拼接文件名
fileName = UUIDUtils.getUUID() + "_" + fileName;
// 获取文件输入流对象
InputStream is = item.getInputStream();
// 创建文件输出流对象,将文件写出到磁盘中
FileOutputStream fos = new FileOutputStream("D:\\IdeaProjects\\chapter_five\\lagou_edu_home\\upload\\" + fileName);
// 使用工具类拷贝文件
IOUtils.copy(is, fos);
// 关闭资源
fos.close();
is.close();
}
}
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}