jsp实现基于web的文件上传的进度控制说明书.doc_第1页
jsp实现基于web的文件上传的进度控制说明书.doc_第2页
jsp实现基于web的文件上传的进度控制说明书.doc_第3页
jsp实现基于web的文件上传的进度控制说明书.doc_第4页
jsp实现基于web的文件上传的进度控制说明书.doc_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1.引言 基于浏览器的文件上传,特别是对于通过标签来实现上传的情况, 存在着严重的性能问题,因为用户提交了文件之后,在浏览器把文件上传到服务器的过程中,界面看上去似乎是静止的,如果是小文件还好些,如果不幸需要上传的是几兆、几十兆甚至上百兆的文件,我相信那是一种非常痛苦的体验,我们中间的很多人应该都有过此种不堪的经历。(一笑)现在我就针对这个问题给出一个解决方案,我们将实现一个具有监控能力的WEB上传的程序它不仅把文件上传到服务器,而且实时地监视文件上传的实际过程。解决方案的基本思路是这样的: 在Form提交上传文件同时,使用AJAX周期性地从Servlet轮询上传状态信息 然后,根据此信息更新进度条和相关文字,及时反映文件传输状态 如果用户取消上传操作,则进行相应的现场清理工作:删除已经上传的文件,在Form提交页面中显示相关信息 如果上传完毕,显示已经上传的文件内容(或链接) 在介绍源代码之前,我们先来看看程序运行界面:2.实现代码 实现代码想当然的有服务器端代码和客户端代码(呵呵),我们先从服务器端开始。2.1.服务器端代码2.1.1.文件上传状态类(FileUploadStatus) 使用FileUploadStatus这个类记录文件上传状态,并将其作为服务器端与web客户端之间通信的媒介,通过对这个类对象提供上传状态作为服务器回应发送给web客户端, web客户端使用JavaScript获得文件上传状态。源代码如下:/* * 本例程演示了通过Web上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。 * 如果需要转载本例程,请您注明作者。 * * 作者: 刘作晨 * EMail: */package liuzuochen.sample.upload;import java.util.*;public class FileUploadStatus /上传用户地址 private String uploadAddr; /上传总量 private long uploadTotalSize = 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 processRunningTime = 0l; /上传文件URL列表 private List uploadFileUrlList = new ArrayList(); /取消上传 private boolean cancel = false; /上传base目录 private String baseDir = ; public FileUploadStatus() public String getBaseDir() return baseDir; public void setBaseDir(String baseDir) this.baseDir = baseDir; public boolean 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 processRunningTime; public void setProcessRunningTime(long processRunningTime) cessRunningTime = processRunningTime; public long getProcessEndTime() return processEndTime; public void setProcessEndTime(long processEndTime) cessEndTime = processEndTime; public long getProcessStartTime() return processStartTime; public void setProcessStartTime(long processStartTime) cessStartTime = processStartTime; public long getReadTotalSize() return readTotalSize; public void setReadTotalSize(long readTotalSize) this.readTotalSize = readTotalSize; public int getSuccessUploadFileCount() return successUploadFileCount; public void setSuccessUploadFileCount(int successUploadFileCount) this.successUploadFileCount = successUploadFileCount; public int getCurrentUploadFileNum() return currentUploadFileNum; public void setCurrentUploadFileNum(int currentUploadFileNum) this.currentUploadFileNum = 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.uploadTotalSize = 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().append(,) .append(CurrentUploadFileNum:).append(getCurrentUploadFileNum(). append(,) .append(SuccessUploadFileCount:).append( getSuccessUploadFileCount().append(,) .append(Status:).append(getStatus().append(,) .append(ProcessStartTime:).append(getProcessStartTime(). append(,) .append(ProcessEndTime:).append(getProcessEndTime().append( ,) .append(ProcessRunningTime:).append(getProcessRunningTime(). append(,) .append(Cancel:).append(getCancel().append(); return strJSon.toString(); 2.1.2.文件上传状态侦听类(FileUploadListener) 使用Common-FileUpload 1.2版本(20070103)。此版本提供了能够监视文件上传情况的ProcessListener接口,使开发者通过FileUploadBase类对象的setProcessListener方法植入自己的Listener。 FileUploadListener类实现了ProcessListener,在整个文件上传过程中,它对上传进度进行监控,并且根据上传 情况实时的更新上传状态Bean。源代码如下:/* * 本例程演示了通过Web上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。 * 如果需要转载本例程,请您注明作者。 * * 作者: 刘作晨 * EMail: */package liuzuochen.sample.upload;import mons.fileupload.ProgressListener;import javax.servlet.http.HttpServletRequest;public class FileUploadListener implements ProgressListenerprivate HttpServletRequest request=null;public FileUploadListener(HttpServletRequest request)this.request=request;/* * 更新状态 */public void update(long pBytesRead, long pContentLength, int pItems)FileUploadStatus statusBean= BackGroundService.getStatusBean(request);statusBean.setUploadTotalSize(pContentLength);/读取完成 if (pContentLength = -1) statusBean.setStatus(完成对 + pItems +个文件的读取:读取了 + pBytesRead + bytes.); statusBean.setReadTotalSize(pBytesRead); statusBean.setSuccessUploadFileCount(pItems); statusBean.setProcessEndTime(System.currentTimeMillis(); statusBean.setProcessRunningTime(statusBean.getProcessEndTime(); /读取中 else statusBean.setStatus(当前正在处理第 + pItems +个文件:已经读取了 + pBytesRead + / + pContentLength+ bytes.); statusBean.setReadTotalSize(pBytesRead); statusBean.setCurrentUploadFileNum(pItems); statusBean.setProcessRunningTime(System.currentTimeMillis(); BackGroundService.saveStatusBean(request,statusBean);2.1.3.后台服务类(BackGroundService) BackGroundService这个Servlet类负责接收Form Post数据、回应状态轮询请求、处理取消文件上传的请求。 尽管可以把这些功能相互分离开来,但为了简单明了,还是将它们放到Servlet中,只是由不同的方法进行分割。 源代码如下:/* * 本例程演示了通过Web上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。 * 如果需要转载本例程,请您注明作者。 * * 作者: 刘作晨 * EMail: */package liuzuochen.sample.upload;/* * Title: 后台服务 * * Description: 为客户端提供上传及文件传输状态查询服务 * */import java.io.File;import java.io.IOException;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;import 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(); protected 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); else return filePath; /* * 从request中取出FileUploadStatus Bean */ public static FileUploadStatus getStatusBean( HttpServletRequest request) BeanControler beanCtrl = BeanControler.getInstance(); return beanCtrl.getUploadStatus(request.getRemoteAddr(); /* * 把FileUploadStatus Bean保存到类控制器BeanControler */ public static void saveStatusBean( HttpServletRequest request, FileUploadStatus statusBean) statusBean.setUploadAddr(request.getRemoteAddr(); BeanControler beanCtrl = BeanControler.getInstance(); beanCtrl.setUploadStatus(statusBean); /* * 删除已经上传的文件 */ private void deleteUploadedFile(HttpServletRequest request) FileUploadStatus satusBean = getStatusBean(request); for (int i = 0; i satusBean.getUploadFileUrlList().size(); i+) File uploadedFile = new File(request.getRealPath(UPLOAD_DIR) + File.separator + satusBean.getUploadFileUrlList(). get(i); uploadedFile.delete(); satusBean.getUploadFileUrlList().clear(); satusBean.setStatus(删除已上传的文件); saveStatusBean(request, satusBean); /* * 上传过程中出错处理 */ private void uploadExceptionHandle( HttpServletRequest request, String errMsg) throws ServletException, IOException /首先删除已经上传的文件 deleteUploadedFile(request); FileUploadStatus satusBean = getStatusBean(request); satusBean.setStatus(errMsg); saveStatusBean(request, satusBean); /* * 初始化文件上传状态Bean */ private FileUploadStatus initStatusBean(HttpServletRequest request) FileUploadStatus satusBean = new FileUploadStatus(); satusBean.setStatus(正在准备处理); satusBean.setUploadTotalSize(request.getContentLength(); satusBean.setProcessStartTime(System.currentTimeMillis(); satusBean.setBaseDir(request.getContextPath() + UPLOAD_DIR); return satusBean; /* * 处理文件上传 */ private void processFileUpload(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException DiskFileItemFactory factory = new DiskFileItemFactory(); /设置内存缓冲区,超过后写入临时文件 factory.setSizeThreshold(10240000); /设置临时文件存储位置 factory.setRepository(new File(request.getRealPath(/upload/temp); ServletFileUpload upload = new ServletFileUpload(factory); /设置单个文件的最大上传值 upload.setFileSizeMax(102400000); /设置整个request的最大值 upload.setSizeMax(102400000); upload.setProgressListener(new FileUploadListener(request); /保存初始化后的FileUploadStatus Bean saveStatusBean(request, initStatusBean(request); String forwardURL = ; try List items = upload.parseRequest(request); /获得返回url for (int i = 0; i items.size(); i+) FileItem item = (FileItem) items.get(i); if (item.isFormField() forwardURL = item.getString(); break; /处理文件上传 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 = getStatusBean(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(); 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(); /* * 处理取消文件上传 */ private void processCancelFileUpload(HttpServletRequest request, HttpServletResponse response) throws IOException FileUploadStatus satusBean = getStatusBean(request); satusBean.setCancel(true); saveStatusBean(request, satusBean); responseStatusQuery(request, response); protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException boolean isMultipart = ServletFileUpload.isMultipartContent(request); if (isMultipart) processFileUpload(request, response); else request.setCharacterEncoding(UTF-8); if (request.getParameter(uploadStatus) != null) responseStatusQuery(request, response); if (request.getParameter(cancelUpload) != null) processCancelFileUpload(request, response); 2.1.4.文件上传状态控制类(BeanControler) 这是一个单例类,它的功能是为客户端保存文件上传状态,这里我没有使用Session来存储文件上传状态,因为对于AJAX这种异步调用,服务器会开启不同的Session,所以无法通过Session保存文件上传状态。 我并不认为这种方法最好,如果有更好的方法,欢迎大家一起讨论。 源代码如下:/* * 本例程演示了通过Web上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。 * 如果需要转载本例程,请您注明作者。 * * 作者: 刘作晨 * EMail: */package liuzuochen.sample.upload;/* * Title: 类控制器 * * Description: 主要作用是对FileUploadStatus进行管理,为客户端提供相应的 * FileUploadStatus类对象。这是一个单例类。 * */import java.util.Vector;public class BeanControler private static BeanControler beanControler = new BeanControler(); private Vector vector = new Vector(); private BeanControler() public static BeanControler getInstance() return beanControler; /* * 取得相应FileUploadStatus类对象的存储位置 */ private int indexOf(String strID) int nReturn = -1; for (int i = 0; i vector.size(); i+) FileUploadStatus status = (FileUploadStatus) vector.elementAt(i); if (status.getUploadAddr().equals(strID) nReturn = i; break; return nReturn; /* * 取得相应FileUploadStatus类对象 */ public FileUploadStatus getUploadStatus(String strID) return (FileUploadStatus) vector.elementAt(indexOf(strID); /* * 存储FileUploadStatus类对象 */ public void setUploadStatus(FileUploadStatus status) int nIndex = indexOf(status.getUploadAddr(); if ( -1 = nIndex) vector.add(status); else vector.insertElementAt(status, nIndex); vector.removeElementAt(nIndex + 1); /* * 删除FileUploadStatus类对象 */ public void removeUploadStatus(String strID) int nIndex = indexOf(strID); if(-1!=nIndex) vector.removeElementAt(nIndex); 2.2.客户端代码 客户端我们采用Prototype框架。请下载。2.2.1.AjaxWrapper.js AjaxWrapper.js对Prototype进行了封装。请下载分析2.2.2.fileUpload.html fileUpload.html是文件上传界面。 请下载。 2.2.3.result.jsp result.jsp是文件上传结果显示界面。 请下载 2.2.4.fileUpload.css fileUpload.css是样式文件。 源代码如下:body color:#000;background-color:white;font:15px Georgia, Lucida Grande, Arial, sans-serif; letter-spacing:0.01em;margin:15px;#controlPanel,#resultPanelwidth:700px;margin:20px auto;padding:25px;border:3px solid gray;-moz-border-radius:10px;background:#f8f8f8;#errorAreawidth:400px;margin:20px auto;padding:25px;border:3px solid gray;-moz-border-radius:10px;background:red;#normalMessageAreawidth:400px;margin:20px auto;padding:25px;border:3px solid gray;-moz-border-radius:10px;background:yellow;#progressBar pad

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论