1、 1 1. 引言 基于浏览器的文件上传,特别是对于通过 标签来实现上传的情况, 存在着严重的性能问题,因为用户提交了文件之后,在浏览器把文件上传到服务器的过程中,界面看上去似乎是静止的,如果是小文件还好些,如果不幸需要上传的是几兆、几十兆甚至上百兆的文件,我相信那是一种非常痛苦的体验,我们中间的很多人应该都有过此种不堪的经历。(一笑) 现在我就针对这个问题给出一个解决方案,我们将实现一个具有监控能力的 WEB 上传的程序 它不仅把文件上传到服务器,而且 “实时地 “监视文件 上传的实际过程。 解决方案的基本思路是这样的: 在 Form 提交上传文件同时,使用 AJAX 周期性地从 Servle
2、t 轮询上传状态信息 然后,根据此信息更新进度条和相关文字,及时反映文件传输状态 如果用户取消上传操作,则进行相应的现场清理工作:删除已经上传的文件,在 Form 提交页面中显示相关信息 如果上传完毕,显示已经上传的文件内容 (或链接 ) 在介绍源代码之前,我们先来看看程序运行界面: 2. 实现代码 实现代码想当然的有服务器端代码和客户端代码(呵呵),我们先从服务器端开始。 2.1. 服务器端代码 2.1.1. 文件上传状态类( FileUploadStatus) 2 使用 FileUploadStatus这个类记录文件上传状态,并将其作为服务器端与 web客户端之间通信的媒介,通过对这个类对
3、象提供上传状态作为服务器回应发送给 web 客户端, web 客户端使用 JavaScript 获得文件上传状态。源代码如下: /* * 本例程演示了通过 Web 上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。 * 如果需要转载本例程,请您注明作者。 * * 作者: 刘作晨 * EMail: */ package liuzuochen.sample.upload; import java.util.*; public class FileUploadStatus /上传用户地址 private String uploadAddr; /上传总量 private long uploa
4、dTotalSize = 0; /读取上传总量 private long readTotalSize = 0; /当前上传文件号 private int currentUploadFileNum = 0; /成功读取上传文件数 private int successUploadFileCount = 0; /状态 private String status = “; /处理起始时间 private long processStartTime = 0l; /处理终止时间 private long processEndTime = 0l; /处理执行时间 private long processR
5、unningTime = 0l; /上传文件 URL 列表 private List uploadFileUrlList = new ArrayList(); /取消上传 private boolean cancel = false; /上传 base目录 private String baseDir = “; public FileUploadStatus() public String getBaseDir() return baseDir; 3 public void setBaseDir(String baseDir) this.baseDir = baseDir; public bo
6、olean getCancel() return cancel; public void setCancel(boolean cancel) this.cancel = cancel; public List getUploadFileUrlList() return uploadFileUrlList; public void setUploadFileUrlList(List uploadFileUrlList) this.uploadFileUrlList = uploadFileUrlList; public long getProcessRunningTime() return pr
7、ocessRunningTime; public void setProcessRunningTime(long processRunningTime) this.processRunningTime = processRunningTime; public long getProcessEndTime() return processEndTime; public void setProcessEndTime(long processEndTime) this.processEndTime = processEndTime; public long getProcessStartTime()
8、 return processStartTime; public void setProcessStartTime(long processStartTime) this.processStartTime = processStartTime; public long getReadTotalSize() return readTotalSize; public void setReadTotalSize(long readTotalSize) this.readTotalSize = readTotalSize; public int getSuccessUploadFileCount()
9、return successUploadFileCount; public void setSuccessUploadFileCount(int successUploadFileCount) this.successUploadFileCount = successUploadFileCount; 4 public int getCurrentUploadFileNum() return currentUploadFileNum; public void setCurrentUploadFileNum(int currentUploadFileNum) this.currentUploadF
10、ileNum = currentUploadFileNum; public String getStatus() return status; public void setStatus(String status) this.status = status; public long getUploadTotalSize() return uploadTotalSize; public String getUploadAddr() return uploadAddr; public void setUploadTotalSize(long uploadTotalSize) this.uploa
11、dTotalSize = uploadTotalSize; public void setUploadAddr(String uploadAddr) this.uploadAddr = uploadAddr; public String toJSon() StringBuffer strJSon = new StringBuffer(); strJSon.append(“UploadTotalSize:“).append(getUploadTotalSize().append( “,“) .append(“ReadTotalSize:“).append(getReadTotalSize().a
12、ppend(“,“) .append(“CurrentUploadFileNum:“).append(getCurrentUploadFileNum(). append(“,“) .append(“SuccessUploadFileCount:“).append( getSuccessUploadFileCount().append(“,“) .append(“Status:“).append(getStatus().append(“,“) .append(“ProcessStartTime:“).append(getProcessStartTime(). append(“,“) .appen
13、d(“ProcessEndTime:“).append(getProcessEndTime().append( 5 “,“) .append(“ProcessRunningTime:“).append(getProcessRunningTime(). append(“,“) .append(“Cancel:“).append(getCancel().append(“); return strJSon.toString(); 2.1.2. 文件上传状态侦听类( FileUploadListener) 使用 Common-FileUpload 1.2 版本 (20070103)。此版本提供了能够监
14、视文件上传情况的ProcessListener接口,使开发者通过 FileUploadBase 类对象的 setProcessListener方法植入自己的 Listener。 FileUploadListener 类实现了 ProcessListener,在整个文件上传过程中,它对上传进度进行监控,并且根据上传 情况实时的更新上传状态 Bean。源代码如下: /* * 本例程演示了通过 Web 上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。 * 如果需要转载本例程,请您注明作者。 * * 作者: 刘作晨 * EMail: */ package liuzuochen.sample
15、.upload; import mons.fileupload.ProgressListener; import javax.servlet.http.HttpServletRequest; public class FileUploadListener implements ProgressListener private HttpServletRequest request=null; public FileUploadListener(HttpServletRequest request) this.request=request; /* * 更新状态 */ public void up
16、date(long pBytesRead, long pContentLength, int pItems) FileUploadStatus statusBean= BackGroundService.getStatusBean(request); statusBean.setUploadTotalSize(pContentLength); /读取完成 if (pContentLength = -1) statusBean.setStatus(“完成对 “ + pItems +“个文件的读取 :读取了 “ + pBytesRead + “ bytes.“); 6 statusBean.set
17、ReadTotalSize(pBytesRead); statusBean.setSuccessUploadFileCount(pItems); statusBean.setProcessEndTime(System.currentTimeMillis(); statusBean.setProcessRunningTime(statusBean.getProcessEndTime(); /读取中 else statusBean.setStatus(“当前正在处理第 “ + pItems +“个文件 :已经读取了 “ + pBytesRead + “/“ + pContentLength+ “
18、bytes.“); statusBean.setReadTotalSize(pBytesRead); statusBean.setCurrentUploadFileNum(pItems); statusBean.setProcessRunningTime(System.currentTimeMillis(); BackGroundService.saveStatusBean(request,statusBean); 2.1.3. 后台服务类( BackGroundService) BackGroundService 这个 Servlet 类负责接收 Form Post 数据、回应状态轮询请求、
19、处理取消文件上传的请求。 尽管可以把这些功能相互分 离开来,但为了简单明了,还是将它们放到 Servlet 中,只是由不同的方法进行分割。 源代码如下: /* * 本例程演示了通过 Web 上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。 * 如果需要转载本例程,请您注明作者。 * * 作者: 刘作晨 * EMail: */ package liuzuochen.sample.upload; /* * Title: 后台服务 * * Description: 为客户端提供上传及文件传输状态查 询服务 * */ import java.io.File; import java.io.
20、IOException; 7 import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import mons.fileupload.FileItem; import mons.fileupload.FileUploadException; import mons.fileupload.disk.DiskFileItemFactory; impo
21、rt mons.fileupload.servlet.*; public class BackGroundService extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet public static final String UPLOAD_DIR = “/upload“; public static final String DEFAULT_UPLOAD_FAILURE_URL = “./result.jsp“; public BackGroundService() super(); protecte
22、d void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException doPost(request, response); /* * 从文件路径中取出文件名 */ private String takeOutFileName(String filePath) int pos = filePath.lastIndexOf(File.separator); if (pos 0) return filePath.substring(pos + 1); el
23、se return filePath; /* * 从 request 中取出 FileUploadStatus Bean */ public static FileUploadStatus getStatusBean( HttpServletRequest request) BeanControler beanCtrl = BeanControler.getInstance(); return beanCtrl.getUploadStatus(request.getRemoteAddr(); /* * 把 FileUploadStatus Bean 保存到类控制器 BeanControler
24、8 */ public static void saveStatusBean( HttpServletRequest request, FileUploadStatus statusBean) statusBean.setUploadAddr(request.getRemoteAddr(); BeanControler beanCtrl = BeanControler.getInstance(); beanCtrl.setUploadStatus(statusBean); /* * 删除已经上传的文件 */ private void deleteUploadedFile(HttpServlet
25、Request request) FileUploadStatus satusBean = getStatusBean(request); for (int i = 0; i 0) String fileName = takeOutFileName(item.getName(); File uploadedFile = new File(request.getRealPath(UPLOAD_DIR) + File.separator + fileName); item.write(uploadedFile); /更新上传文件列表 FileUploadStatus satusBean = get
26、StatusBean(request); satusBean.getUploadFileUrlList().add(fileName); saveStatusBean(request, satusBean); Thread.sleep(500); catch (FileUploadException e) uploadExceptionHandle(request, “上传文件时发生错误 :“ + e.getMessage(); catch (Exception e) uploadExceptionHandle(request, “保存上传文件时发生错误 :“ + e.getMessage()
27、; if (forwardURL.length() = 0) forwardURL = DEFAULT_UPLOAD_FAILURE_URL; request.getRequestDispatcher(forwardURL).forward(request, response); /* * 回应上传状态查询 */ private void responseStatusQuery(HttpServletRequest request, HttpServletResponse response) throws IOException response.setContentType(“text/xml“); response.setHeader(“Cache-Control“, “no-cache“); FileUploadStatus satusBean = getStatusBean(request); response.getWriter().write(satusBean.toJSon();
Copyright © 2018-2021 Wenke99.com All rights reserved
工信部备案号:浙ICP备20026746号-2
公安局备案号:浙公网安备33038302330469号
本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。