文件上传
1、准备工作
-
创建项目,用maven创建尽量不要手动导包,避免出现web.xml实例化错误。
-
导入common-io和common-fileupload包:
地址:https://mvnrepository.com/artifact/commons-io/commons-io/2.6
https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload/1.4
-
maven导包
<dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-io/commons-io --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency>
2、注意事项
- 为保证服务器安全,文件上传可存放在WEB-INF目录下
- 为防止文件覆盖,要使文件名不同,可用uuid
- 要限制文件大小
- 可以根据文件后缀限制文件格式
3、代码实现
-
判断前端请求的表单是否含有文件 enctype=“multipart/form-data”
if (!ServletFileUpload.isMultipartContent(req)) { return; }
-
因为get方法传的参数大小有限制,所以要用post方法 method=“post”
<form action="${pageContext.request.contextPath}/f1" enctype="multipart/form-data" method="post"> <p><input type="text" name="name"><br> <input type="file" name="file1"><br> <input type="file" name="file2"><br> <input type="submit"> | <input type="reset"></p> </form>
-
设置存放路径和临时存放路径
// 创建文件存放路径 String uploadPath = this.getServletContext().getRealPath("WEB-INF/uploadPath"); File uploadFile = new File(uploadPath); if (!uploadFile.exists()) { uploadFile.mkdir(); } // 创建临时存放路径 String tmpPath = this.getServletContext().getRealPath("WEB-INF/tmpPath"); File file = new File(tmpPath); if (!uploadFile.exists()) { file.mkdir(); }
-
创建 DiskFileItemFactory
public DiskFileItemFactory getDiskFileItemFactory(File file) { DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setRepository(file); // 设置临时文件存放位置 factory.setSizeThreshold(1024 * 1024); /// 设置缓冲区大小 factory.setDefaultCharset("utf-8"); // 设置字符集 return factory; }
-
创建FileUpload
public FileUpload getFileUpload(DiskFileItemFactory factory) { FileUpload upload = new FileUpload(); upload.setFileItemFactory(factory); // 也可以通过构造器传FileUpload upload = new FileUpload(factory); upload.setFileSizeMax(1024 * 1024); // 设置文件最大为(单个文件最大) 1M upload.setSizeMax(1024 * 1024 * 15); // 设置最大存放总量(所有文件加起来) 15m upload.setHeaderEncoding("utf-8"); // 指定编码 upload.setProgressListener(new ProgressListener() { // 监听 @Override public void update(long l, long l1, int i) { // l:文件大小 l1文件已上传的大小 System.out.println("已上传" + l1 + "/" + l); } }); return upload; }
-
封装文件对象,判断是否是文件,将文件转换为流, 拼接文件路径,写入服务器
public String msg(FileUpload upload, String uploadPath, HttpServletRequest req) { List<FileItem> fileItems = null; InputStream in = null; FileOutputStream fos = null; String msg = "文件上传失败"; try { fileItems = upload.parseRequest(req); for (FileItem fileItem : fileItems) { if (fileItem.isFormField()) { // 判断是否是文件, 不是则不用上传 true不是文件 String name = fileItem.getFieldName(); // 获取表单的name String value = fileItem.getString("utf-8"); // 获取到输入的值 System.out.println(name + ":" + value); } else { String uploadFileName = fileItem.getName(); // 获取文件名路径 System.out.println("文件路径" + uploadFileName); if (uploadFileName.trim().equals("") || uploadFileName == null) { continue; // 如果文件名为空 } String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("\\") + 1); // 获取文件名 String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1); // 获取文佳格式 System.out.println("文件信息 [件名:" + fileName + "---文件类型" + fileExtName + "]"); // uuid创建文目录防止文件覆盖 String uuidPath = UUID.randomUUID().toString(); // 拼接文件存放路径 String realPath = uploadPath + "\\" + uuidPath; File realPathFile = new File(realPath); // 如果没有该目录创建目录 if (!realPathFile.exists()) { realPathFile.mkdir(); } // 将文件转变换为流 in = fileItem.getInputStream(); fos = new FileOutputStream(realPath + "\\" + fileName); byte[] buffer = new byte[1024 * 1024]; int len = 0; while ((len = in.read(buffer)) != -1) { fos.write(buffer, 0, len); } msg = "文件上传成功"; fileItem.delete(); //上传成功,清除临时文件 } } } catch (Exception e) { e.printStackTrace(); } finally { try { in.close(); fos.close(); } catch (IOException e) { e.printStackTrace(); } } return msg; }
4、完整代码
1. Fileup.java
package com.kuang.servlet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.ProgressListener;
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.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;
public class FileUp1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
if (!ServletFileUpload.isMultipartContent(req)) { // 判断表单是否有 enctype="multipart/form-data"
return;
}
// 创建文件存放路径
String uploadPath = this.getServletContext().getRealPath("WEB-INF/uploadPath");
File uploadFile = new File(uploadPath);
if (!uploadFile.exists()) {
uploadFile.mkdir();
}
// 创建临时存放路径
String tmpPath = this.getServletContext().getRealPath("WEB-INF/tmpPath");
File file = new File(tmpPath);
if (!uploadFile.exists()) {
file.mkdir();
}
DiskFileItemFactory factory = getDiskFileItemFactory(file);
FileUpload upload = getFileUpload(factory);
String msg = msg(upload, uploadPath, req);
req.setAttribute("msg", msg);
req.getRequestDispatcher("/msg.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
public DiskFileItemFactory getDiskFileItemFactory(File file) {
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(file); // 设置临时文件存放位置
factory.setSizeThreshold(1024 * 1024); /// 设置缓冲区大小
factory.setDefaultCharset("utf-8"); // 设置字符集
return factory;
}
public FileUpload getFileUpload(DiskFileItemFactory factory) {
FileUpload upload = new FileUpload();
upload.setFileSizeMax(1024 * 1024); // 设置文件最大为(单个文件最大) 1M
upload.setSizeMax(1024 * 1024 * 15); // 设置最大存放总量(所有文件加起来) 15m
upload.setHeaderEncoding("utf-8"); // 指定编码
upload.setFileItemFactory(factory); // 也可以通过构造器传FileUpload upload = new FileUpload(factory);
upload.setProgressListener(new ProgressListener() { // 监听
@Override
public void update(long l, long l1, int i) { // l1:文件大小 l文件已上传的大小
System.out.println("已上传" + l + "/" + l1);
}
});
return upload;
}
public String msg(FileUpload upload, String uploadPath, HttpServletRequest req) {
List<FileItem> fileItems = null;
InputStream in = null;
FileOutputStream fos = null;
String msg = "文件上传失败";
try {
fileItems = upload.parseRequest(req);
for (FileItem fileItem : fileItems) {
if (fileItem.isFormField()) { // 判断是否是文件, 不是则不用上传 true不是文件
String name = fileItem.getFieldName(); // 获取表单的name
String value = fileItem.getString("utf-8"); // 获取到用户输入的值
System.out.println(name + ":" + value);
} else {
String uploadFileName = fileItem.getName(); // 获取文件名路径
System.out.println("文件路径" + uploadFileName);
if (uploadFileName.trim().equals("") || uploadFileName == null) {
continue; // 如果文件名为空
}
String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("\\") + 1); // 获取文件名
String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1); // 获取文佳格式
System.out.println("文件信息 [件名:" + fileName + "---文件类型" + fileExtName + "]");
// uuid创建文目录防止文件覆盖
String uuidPath = UUID.randomUUID().toString();
// 拼接文件存放路径
String realPath = uploadPath + "\\" + uuidPath;
File realPathFile = new File(realPath);
// 如果没有该目录创建目录
if (!realPathFile.exists()) {
realPathFile.mkdir();
}
// 将文件转变换为流
in = fileItem.getInputStream();
fos = new FileOutputStream(realPath + "\\" + fileName);
byte[] buffer = new byte[1024 * 1024];
int len = 0;
while ((len = in.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
msg = "文件上传成功";
fileItem.delete(); //上传成功,清除临时文件
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
in.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return msg;
}
}
2.index.jsp
<%--
Created by IntelliJ IDEA.
User: WH
Date: 2022/4/28
Time: 15:28
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/f1" enctype="multipart/form-data" method="post">
<p><input type="text" name="name"><br>
<input type="file" name="file1"><br>
<input type="file" name="file2"><br>
<input type="submit"> | <input type="reset"></p>
</form>
</body>
</html>
3、web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
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"
version="4.0"
metadata-complete="true">
<servlet>
<servlet-name>FileUp1</servlet-name>
<servlet-class>com.kuang.servlet.FileUp1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileUp1</servlet-name>
<url-pattern>/f1</url-pattern>
</servlet-mapping>
</web-app>
4、msg.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>消息提示</title>
</head>
<body>
${msg}
</body>
</html>