文件上传(java Web)
1、导入依赖
1.1、在maven下载依赖,仓库地址:https://mvnrepository.com/
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</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、Tomcat配置
y\AppData\Roaming\Typora\typora-user-images\image-20220313203055951.png)]
如果没有上图的filetest:war exploded,点击file——》Project Settings ——》Artifacts 看下图
在重新回到刚刚的Tomcat配置页面添加
3、前景知识
UUID:是让分布式系统中的所有元素,都能有唯一的辨识资讯,而不需要透过中央控制端来做辨识资讯的指定。如此一来,每个人都可以建立不与其它人冲突的 UUID。在这样的情况下,就不需考虑数据库建立时的名称重复问题。
文件上传注意事项(优化):
-
为了保证服务器安全,上传文件应该放在外界无法访问的目录下
-
为了防止文件覆盖的现象,要为上传文件产生一个唯一的文件名(一般使用UUID、mds…)
-
要限制文件的最大值
-
可以限制文件类型,在收到上传文件名时,判断后缀名是否合法
申明:网络传输中的东西,都需要序列化
public class User implements Serializable {
}
4、编写代码
前端代码:
index.jsp
<%--
Created by IntelliJ IDEA.
User: hy
Date: 2022/3/12
Time: 19:47
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>
<%--通过表单上传文件
get:上传文件大小有限制
post:上传文件大小没限制
--%>
<form action="${pageContext.request.contextPath}/upload.do" method="post" enctype="multipart/form-data">
用户名:<input name="user" value="上传用户名">
<p>
<input type="file" name="file1">
</p>
<p>
<input type="file" name="file2">
</p>
<input type="submit"> <input type="reset">
</form>
</body>
</html>
info.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>成功页面</title>
</head>
<body>
<p>${msg}</p>
</body>
</html>
后台代码:
web.xml
<servlet>
<servlet-name>FileServlet</servlet-name>
<servlet-class>com.liu.study.servlet.Fileservlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern>/upload.do</url-pattern>
</servlet-mapping>
package com.liu.study.servlet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.UUID;
public class Fileservlet extends javax.servlet.http.HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//判断文件是普通表单还是带文件的表单
if (!ServletFileUpload.isMultipartContent(req)) {
return;//终止方法,说明这是一个普通表单,直接返回
}
//创建上传文件保存路径,存放/WEB-INF/下,安全,用户无法之直接访问
String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
File uploadFile = new File(uploadPath);
if (!uploadFile.exists()) {
uploadFile.mkdir();
}
//创建上传文件临时保存路径
String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");
File file = new File(tmpPath);
if (!file.exists()) {
file.mkdir();
}
try {
//创建DiskFileItemFactory对象,处理文件上传路径或者大小限制
DiskFileItemFactory factory = getDiskFileItemFactory(file);
ServletFileUpload upload = getServletFileUpload(factory);
String msg = uploadParseRequest(upload, req, uploadPath);
req.setAttribute("msg", msg);
//转发
req.getRequestDispatcher("info.jsp").forward(req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {
//创建servletFileUpload对象
ServletFileUpload upload = new ServletFileUpload(factory);
//监听器,监控文件上传进度
upload.setProgressListener(new ProgressListener() {
//pBytesRead:文件已上传的大小,pContentLength:文件总大小
@Override
public void update(long pBytesRead, long pContentLength, int pItems) {
System.out.println("总大小:" + pContentLength + " 已上传:" + pBytesRead);
}
});
//设置文件编码,解决乱码问题
upload.setHeaderEncoding("utf-8");
//设置文件最大上传大小
upload.setFileSizeMax(1024 * 1024 * 10);
upload.setSizeMax(1024 * 1024 * 10);
return upload;
}
public static DiskFileItemFactory getDiskFileItemFactory(File file) {
DiskFileItemFactory factory = new DiskFileItemFactory();
//通过这个工厂设置一个缓冲区,当上传文件大于缓冲区,将它存入临时文件中
factory.setSizeThreshold(1024 * 1024);
factory.setRepository(file);
return factory;
}
public static String uploadParseRequest(ServletFileUpload upload, HttpServletRequest request, String uploadPath) throws FileUploadException, IOException {
String msg = "";
//
List<FileItem> fileItems = upload.parseRequest(request);
//遍历fileItem
for (FileItem fileItem : fileItems) {
if (fileItem.isFormField()) {//判断是普通表单还是带文件表单,ture->普通表单
String name = fileItem.getFieldName();//获取表单名字
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;
}
//获取上传名字,eg:/img/img.png -> img.png
String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
//获取上传对象类型,eg:/img/img.png ->png
String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
System.out.println("文件信息:文件名:" + fileName + "文件类型" + fileExtName);
//使用UUID生成唯一的一串字符,作用:防止文件覆盖现象,序列化后也唯一;网络传输必定序列化
String uuidPath = UUID.randomUUID().toString();
// 拼接路径:uploadPath/uuidPath
String realPath = uploadPath + "/" + uuidPath;
File realPathFile = new File(realPath);
if (!realPathFile.exists()) {//如果路径不存在则创建文件
realPathFile.mkdir();
}
//获取io流对象(输入流)
InputStream inputStream = fileItem.getInputStream();
//创建FileOutputStream(文件输出流)对象
FileOutputStream fos = new FileOutputStream(realPath + "/" + fileName);
//设置缓冲区
byte[] buffer = new byte[1024 * 1024];
//读取字节数
int len = 0;
//len=-1,文件读取完毕
while ((len = inputStream.read(buffer)) > 0) {//读取文件
//存入文件
fos.write(buffer, 0, len);
}
//关闭资源
fos.close();
inputStream.close();
msg = "上传成功了!!!!";
fileItem.delete();
}
}
return msg;
}
}
fos.write(buffer, 0, len);
}
//关闭资源
fos.close();
inputStream.close();
msg = "上传成功了!!!!";
fileItem.delete();
}
}
return msg;
}