一、文件上传的介绍
1.文件上传的实质:文件的拷贝
文件上传:从本地将文件拷贝到服务器磁盘上
客户端:需要编写文件上传表单服务端:需要编写代码接收上传的文件
二、客户端编码
1.文件上传三要素
表单的提交方式:post(get方式提交数据有大小限制)表达的enctype属性值:必须设置为 multipart/form-data multipart/form-data:多部件文件上传,指表单数据有多部分构成。 既可以有文本数据,也可以有文件等二进制数据。表单中必须有文件上传项:file,必须有name属性和值
注意:默认情况下,表单的enctype的值是application/x-www-form-urlencoded,不能用于文件上传,只有使用了multipart/form-data,才能完整的传递文件数据
2.代码实例
浏览器文件上传
三、服务器端编码
1.上传文件,抓包分析
![在这里插入图片描述](https://img-blog.csdnimg.cn/53b9b6a833f0471d8b49de6acc29b2a7.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBATXlpa0o=,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
2.FileUpload工具类
(1)导入依赖
FileUpload包可以很容易地将文件上传到你的Web应用程序. IOUtils封装了Java中io的常见操作,使用十分方便 ,需要下载 commons-io-1.4.jar 包 .
commons-io
commons-io
1.4
commons-fileupload
commons-fileupload
1.2.1
(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 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);
}
}
|