利用commons工具包实现文件上传
利用commons工具包实现文件上传
一、首先导入commons-io/和commons-fileupload/两个包
二、编写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.HttpServlet;
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 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 tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
File file = new File(tempPath);
if (!file.exists()) {
file.mkdir();
}
String msg = null;
try {
//1.创建 DiskFileItemFactory
DiskFileItemFactory factory = getDiskFileItemFactory(file);
//2.获取ServletFileUpload
ServletFileUpload upload = getServletFileUpload(factory);
// 3.处理上传文件
msg = uploadParseRequest(upload, req, uploadPath);
} catch (FileUploadException e) {
e.printStackTrace();
}
// 请求转发消息
req.setAttribute("msg", msg);
req.getRequestDispatcher("info.jsp").forward(req, resp);
}
public static DiskFileItemFactory getDiskFileItemFactory(File file) {
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(1024 * 1024); // 缓存区大小为1M
factory.setRepository(file); // 临时目录的保存目录,需要一个file
return factory;
}
public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setProgressListener(new ProgressListener() {
@Override
public void update(long pBytesRead, long pContenLength, int pItems) {
System.out.println("总大小:" + pContenLength + "已上传:" + pBytesRead);
}
});
upload.setHeaderEncoding("UTF-8");
upload.setFileSizeMax(1024 * 1024 * 10);
upload.setSizeMax(1024 * 1024 * 10);
return upload;
}
public static String uploadParseRequest(ServletFileUpload upload, HttpServletRequest req, String uploadPath) throws FileUploadException, IOException {
String message = null;
List<FileItem> fileItems = upload.parseRequest(req); // 把前端请求解析,封装成一个FileItem对象
for (FileItem fileItem : fileItems) {
if (fileItem.isFormField()) { // 普通表单
String name = fileItem.getName();
String value = fileItem.getString("utf-8");
System.out.println(name + ":" + value);
} else { //判断是文件表单
String uploadFileName = fileItem.getName(); // ===== 处理文件 =============
if (uploadFileName.trim().equals("") || uploadFileName == null) {
continue;
}
String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
// UUID.randomUUID() 随机生成一个唯一识别的通用码
// 网络中传输东西,都需要序列化
// POJO, 实体类, 如果想要生成在多个电脑上运行, 传输-->需要把对象都序列化
// JNI java native Interface
// implements Serializable :标记接口 ,JVM --> Java栈 本地方法栈 native --> c++
String uuidPath = UUID.randomUUID().toString();// 可以 使用UUID(唯一识别的通用码),保证文件唯一
String realPath = uploadPath + "/" + uuidPath; // ========= 存放地址 ========
File realPathFile = new File(realPath);
if (!realPathFile.exists()) {
realPathFile.mkdir();
}
InputStream is = fileItem.getInputStream(); // ========= 文件传输 ========
FileOutputStream fos = new FileOutputStream(realPath + "/" + fileName);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
fos.close();
is.close();
message = "文件上传成功";
fileItem.delete(); //上传成功,清除临时文件
}
}
return message;
}
}
三、在web.xml注册servlet
<?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_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>FileServlet</servlet-name>
<servlet-class>code.dwx.servlet.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern>/upload.do</url-pattern>
</servlet-mapping>
</web-app>
四、编写index.jsp和info.jsp
index.jsp
<%--
Created by IntelliJ IDEA.
User: yuyuq
Date: 2020/11/20
Time: 20:14
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>upload page</title>
</head>
<body>
<h1>UpLoad</h1>
<form action="${pageContext.request.contextPath}/upload.do" method="post" enctype="multipart/form-data">
上传用户:<input type="text" name="username"> <br>
<p><input type="file" name="file1"></p>
<p><input type="file" name="file2"></p>
<p><input type="submit">|<input type="reset"></p>
</form>
</body>
</html>
info.jsp
<%@ page language="java" contentType="text/html;charset=UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
${msg}
</body>
</html>
五、页面优化
可以利用Layui框架:https://www.layui.com/里面的示例代码
六、文件上传注意事项
- 为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下
- 为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名
- 要限制上传文件的最大值
- 可以限制上传文件的类型,在收到上传文件时,判断后缀名是否合法
作者:余月七 (yuyueq)
出处:http://www.cnblogs.com/yuyueq
警言: 无论人生上到哪一层台阶,阶下有人在仰望你,阶上亦有人在俯视你。你抬头自卑,低头自得,唯有平视,才能看见真实的自己。
转载请注明原文链接:https://www.cnblogs.com/yuyueq/p/14561891.html
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢你的支持!
警言: 无论人生上到哪一层台阶,阶下有人在仰望你,阶上亦有人在俯视你。你抬头自卑,低头自得,唯有平视,才能看见真实的自己。
转载请注明原文链接:https://www.cnblogs.com/yuyueq/p/14561891.html
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢你的支持!