1. 多文件数据的提交
2. 文件数据包接收存储功能
3. 文件数据上传进度
4. WEB页面无刷新异步提交
时序图:
- 文件上传时序图
- 文件上传进度获取时序图
实现思路:
1. 多文件数据的提交
在WEB页面采用多个利用form表单进行文件提交
2. 文件数据包接收存储功能
服务端采用servlet,利用apache common upload组件接收解析数据包,接收解析的过程中保存进度到session, 文件接收完毕后保存到指定目录
3. 文件数据上传进度
在WEB页面在界面写一个定时器,定时访问服务器提供上传进度获取功能的servlet,获取文件上传进度信息
4. WEB页面无刷新异步提交
利用iframe来实现WEB页面无刷新异步上传
关键代码:
UploadFileServlet.java
Java代码
-
package com.test.servlet;
-
import java.io.File;
-
import java.io.IOException;
-
import java.io.Writer;
-
import java.util.Iterator;
-
import java.util.List;
-
import javax.servlet.ServletException;
-
import javax.servlet.http.HttpServlet;
-
import javax.servlet.http.HttpServletRequest;
-
import javax.servlet.http.HttpServletResponse;
-
import org.apache.commons.fileupload.FileItem;
-
import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
-
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
-
import org.apache.commons.fileupload.servlet.FileCleanerCleanup;
-
import org.apache.commons.fileupload.servlet.ServletFileUpload;
-
import org.apache.commons.io.FileCleaningTracker;
-
import org.apache.commons.io.FileUtils;
-
import org.apache.commons.io.FilenameUtils;
-
import org.apache.commons.io.IOUtils;
-
import org.apache.commons.lang3.ArrayUtils;
-
import org.apache.commons.logging.Log;
-
import org.apache.commons.logging.LogFactory;
-
/**
-
* 文件上传数据接收类
-
*
-
* @author chengqi
-
*
-
*/
-
public class UploadFileServlet extends HttpServlet {
-
/** 日志对象*/
-
private Log logger = LogFactory.getLog(this.getClass());
-
private static final long serialVersionUID = 1L;
-
/** 上传目录名*/
-
private static final String uploadFolderName = “uploadFiles”;
-
/** 上传临时文件存储目录*/
-
private static final String tempFolderName = “tempFiles”;
-
/** 上传文件最大为30M*/
-
private static final Long fileMaxSize = 30000000L;
-
/** 允许上传的扩展名*/
-
private static final String [] extensionPermit = {“txt”, “xls”, “zip”};
-
/** 统一的编码格式*/
-
private static final String encode = “UTF-8”;
-
@Override
-
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
logger.info(“UploadFileServlet#doPost() start”);
-
try {
-
String curProjectPath = this.getServletContext().getRealPath(“/”);
-
String saveDirectoryPath = curProjectPath + “/” + uploadFolderName;
-
String tempDirectoryPath = curProjectPath + “/” + tempFolderName;
-
File saveDirectory = new File(saveDirectoryPath);
-
File tempDirectory = new File(tempDirectoryPath);
-
logger.debug(“Project real path [” + saveDirectory.getAbsolutePath() + “]”);
-
//上传时产生的临时文件的默认保存目录
-
logger.debug(“Temp files default save path [” + System.getProperty(“java.io.tmpdir”) + “]”);
-
DiskFileItemFactory factory = new DiskFileItemFactory();
-
//DiskFileItemFactory中DEFAULT_SIZE_THRESHOLD=10240表示如果上传文件大于10K则会产生上传临时文件
-
//上传临时文件的默认目录为java.io.tmpdir中保存的路径,根据操作系统的不同会有区别
-
if(!tempDirectory.exists()) {
-
tempDirectory.mkdir();
-
}
-
//重新设置临时文件保存目录
-
factory.setRepository(tempDirectory);
-
//设置文件清除追踪器,文件上传过程中产生的临时文件会在
-
FileCleaningTracker fileCleaningTracker = FileCleanerCleanup.getFileCleaningTracker(this.getServletContext());
-
factory.setFileCleaningTracker(fileCleaningTracker);
-
ServletFileUpload upload = new ServletFileUpload(factory);
-
//设置文件上传进度监听器
-
FileProcessListener processListener = new FileProcessListener(request.getSession());
-
upload.setProgressListener(processListener);
-
// 设置文件上传的大小限制
-
upload.setFileSizeMax(fileMaxSize);
-
// 设置文件上传的头编码,如果需要正确接收中文文件路径或者文件名
-
// 这里需要设置对应的字符编码,为了通用这里设置为UTF-8
-
upload.setHeaderEncoding(encode);
-
//解析请求数据包
-
List fileItems = upload.parseRequest(request);
-
//遍历解析完成后的Form数据和上传文件数据
-
for (Iterator iterator = fileItems.iterator(); iterator.hasNext()😉 {
-
FileItem fileItem = iterator.next();
-
String fieldName = fileItem.getFieldName();
-
String name = fileItem.getName();
-
//如果为上传文件数据
-
if(!fileItem.isFormField()) {
-
logger.debug(“fieldName[” + fieldName + “] fileName[” + name + "] ");
-
if(fileItem.getSize() > 0) {
-
String fileExtension = FilenameUtils.getExtension(name);
-
if(!ArrayUtils.contains(extensionPermit, fileExtension)) {
-
throw new NoSupportExtensionException(“No Support extension.”);
-
}
-
String fileName = FilenameUtils.getName(name);
-
FileUtils.copyInputStreamToFile(fileItem.getInputStream(),
-
new File(saveDirectory, fileName));
-
}
-
} else { //Form表单数据
-
String value = fileItem.getString(encode);
-
logger.debug(“fieldName[” + value + “] fieldValue[” + fieldName + “]”);
-
}
-
}
-
responseMessage(response, State.OK);
-
} catch(FileSizeLimitExceededException e) {
-
logger.error(e.getMessage(), e);
-
responseMessage(response, State.OVER_FILE_LIMIT);
-
} catch(NoSupportExtensionException e) {
-
logger.error(e.getMessage(), e);
-
responseMessage(response, State.NO_SUPPORT_EXTENSION);
-
} catch(Exception e) {
-
logger.error(e.getMessage(), e);
-
responseMessage(response, State.ERROR);
-
} finally {
-
//清除上传进度信息
-
request.getSession().removeAttribute(“fileUploadProcess”);
-
}
-
logger.info(“UploadFileServlet#doPost() end”);
-
}
-
public enum State {
-
OK(200, “上传成功”),
-
ERROR(500, “上传失败”),
-
OVER_FILE_LIMIT(501, “超过上传大小限制”),
-
NO_SUPPORT_EXTENSION(502, “不支持的扩展名”);
-
private int code;
-
private String message;
-
private State(int code, String message) {
-
this.code = code;
-
this.message = message;
-
}
-
public int getCode() {
-
return code;
-
}
-
public String getMessage() {
-
return message;
-
}
-
}
-
/**
-
* 返回结果函数
-
* @param response
-
* @param state
-
*/
-
private void responseMessage(HttpServletResponse response, State state) {
-
response.setCharacterEncoding(encode);
-
response.setContentType(“text/html; charset=” + encode);
-
Writer writer = null;
-
try {
-
writer = response.getWriter();
-
writer.write(“”);
-
writer.flush();
-
writer.close();
-
} catch(Exception e) {
-
logger.error(e.getMessage(), e);
-
} finally {
-
IOUtils.closeQuietly(writer);
-
}
-
}
-
}
GetFileProcessServlet.java
Java代码
-
package com.test.servlet;
-
import java.io.IOException;
-
import java.io.Writer;
-
import javax.servlet.ServletException;
-
import javax.servlet.http.HttpServlet;
-
import javax.servlet.http.HttpServletRequest;
-
import javax.servlet.http.HttpServletResponse;
-
import org.apache.commons.io.IOUtils;
-
import org.apache.commons.logging.Log;
-
import org.apache.commons.logging.LogFactory;
-
/**
-
* 文件上传进度获取Servlet
-
*
-
* @author chengqi
-
*
-
*/
-
public class GetFileProcessServlet extends HttpServlet {
-
/** 日志对象*/
-
private Log logger = LogFactory.getLog(this.getClass());
-
private static final long serialVersionUID = 1L;
-
@Override
-
protected void doGet(HttpServletRequest request, HttpServletResponse response)
-
throws ServletException, IOException {
-
logger.info(“GetFileProcessServlet#doGet start”);
-
String fileUploadPercent = (String)request.getSession().getAttribute(“fileUploadProcess”);
-
Writer writer = null;
-
try {
-
writer = response.getWriter();
-
logger.info(“percent:” + fileUploadPercent);
-
IOUtils.write(fileUploadPercent == null ? “0%” : fileUploadPercent, writer);
-
writer.flush();
-
writer.close();
-
} catch(Exception e) {
-
logger.error(e.getMessage(), e);
-
} finally {
-
IOUtils.closeQuietly(writer);
-
}
-
logger.info(“GetFileProcessServlet#doGet end”);
-
}
-
}
FileProcessListener.java
Java代码
-
package com.test.servlet;
-
import java.text.NumberFormat;
-
import javax.servlet.http.HttpSession;
-
import org.apache.commons.fileupload.ProgressListener;
-
import org.apache.commons.logging.Log;
-
import org.apache.commons.logging.LogFactory;
-
/**
-
* 文件进度监听器
-
*
-
* @author chengqi
-
*
-
*/
-
public class FileProcessListener implements ProgressListener{
-
/** 日志对象*/
-
private Log logger = LogFactory.getLog(this.getClass());
-
private HttpSession session;
-
public FileProcessListener(HttpSession session) {
-
this.session = session;
-
}
-
public void update(long pBytesRead, long pContentLength, int pItems) {
-
double readByte = pBytesRead;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
文末
从转行到现在,差不多两年的时间,虽不能和大佬相比,但也是学了很多东西。我个人在学习的过程中,习惯简单做做笔记,方便自己复习的时候能够快速理解,现在将自己的笔记分享出来,和大家共同学习。
个人将这段时间所学的知识,分为三个阶段:
第一阶段:HTML&CSS&JavaScript基础
第二阶段:移动端开发技术
第三阶段:前端常用框架
-
推荐学习方式:针对某个知识点,可以先简单过一下我的笔记,如果理解,那是最好,可以帮助快速解决问题;
-
大厂的面试难在,针对一个基础知识点,比如JS的事件循环机制,不会上来就问概念,而是换个角度,从题目入手,看你是否真正掌握。所以对于概念的理解真的很重要。
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
做做笔记,方便自己复习的时候能够快速理解,现在将自己的笔记分享出来,和大家共同学习。
个人将这段时间所学的知识,分为三个阶段:
第一阶段:HTML&CSS&JavaScript基础
第二阶段:移动端开发技术
第三阶段:前端常用框架
-
推荐学习方式:针对某个知识点,可以先简单过一下我的笔记,如果理解,那是最好,可以帮助快速解决问题;
-
大厂的面试难在,针对一个基础知识点,比如JS的事件循环机制,不会上来就问概念,而是换个角度,从题目入手,看你是否真正掌握。所以对于概念的理解真的很重要。
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-RoGTMUDj-1712872571490)]