- 浏览: 624942 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
lry123456:
,没用啊
js 实现div里面的内容滚动,并可以通过按钮控制 -
瑞马23:
uploadifySettings is not a func ...
JQuery上传插件Uploadify并传参数(一) -
wxfcgzht:
qq_26333595 写道我下载部署运行后提示:1、 ...
dsoframer.ocx 实现在线的word编辑 -
qq_26333595:
我下载部署运行后提示:1、TypeError: word.sa ...
dsoframer.ocx 实现在线的word编辑 -
c_hualin:
jpg转换bmp后 jpg文件没发删除呢
JAVA 实现jpg/tif/bmp 等图片之间格式得互相转换
ajax 文件上传进度条
一:方案分析
基于浏览器的文件上传,为了有更好的用户体验,我们一般就设置一个旋转的图标,旋转的图标无法实时的监控文件上传情况。所以我们将实现一个如何实时的监控文件的上传。
参考资料:http://www.cnblogs.com/ybase/archive/2011/11/15/2249298.html
技术问题分析:
- 如何实现上传的功能
- 如何实现上传文件的监听功能
- 如何实现记录上传状态的功能
- 客户端如何状态的实时显示
解决方案:
- 如何实现上传的功能 ------使用apache的FileUpload组件上传文件
- 如何实现上传文件的监听功能 ------使用ProgressListener监听文件状态
- 如何实现记录上传状态的功能 ------使用session保存文件的状态
- 客户端如何状态的实时显示 -------客户端使用AJAX来查询上传的状态
基本思路:
客户端:界面的提交的时候使用<iframe 来实现模拟的无刷新提交,然后在使用ajax来周期的访问servlet并返回sesson中最新的状态信息。
服务器端:在servlet介绍到请求的时候,区分请求的类型是上传的请求还是ajax询问的请求,如果是上传的请求,则执行上传的方法,并启动监听保存上传状态到session中。
在介绍源代码之前,我们先来看看程序运行界面:
接下来是源文件的目录结构:
二、实现代码
UploadFileProgressBar.java ------使用apache的FileUpload组件上传文件
package com.yangpan.upload.progressbar; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Random; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.FileUpload; 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; /** * 有进度条的上传 * * @author 妞见妞爱 * */ public class UploadFileProgressBar extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; //定义允许上传的文件扩展名 protected HashMap<String, String> extMap = new HashMap<String, String>(); //最大文件大小 100 M --测试用 protected long maxSize = 100 * 1024 * 1024; //上传文件的保存路径 protected String configPath = "attached/"; protected String dirTemp = "attached/temp/"; protected String dirName = "file"; public void init() throws ServletException { //定义允许上传的文件扩展名 //extMap.put("image", "gif,jpg,jpeg,png,bmp"); //extMap.put("flash", "swf,flv"); //extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb"); extMap.put("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar"); } /** * 处理上传文件 * @param request * @param response * @throws ServletException * @throws IOException */ @SuppressWarnings("unchecked") public void processFileUpload(HttpServletRequest request, PrintWriter out) throws ServletException, IOException { //文件保存目录路径 String savePath = this.getServletContext().getRealPath("/") + configPath; // 临时文件目录 String tempPath = this.getServletContext().getRealPath("/") + dirTemp; SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM"); String ymd = sdf.format(new Date()); savePath += "/" + ymd + "/"; //创建文件夹 File dirFile = new File(savePath); if (!dirFile.exists()) { dirFile.mkdirs(); } tempPath += "/" + ymd + "/"; //创建临时文件夹 File dirTempFile = new File(tempPath); if (!dirTempFile.exists()) { dirTempFile.mkdirs(); } DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setSizeThreshold(20 * 1024 * 1024); //设定使用内存超过5M时,将产生临时文件并存储于临时目录中。 factory.setRepository(new File(tempPath)); //设定存储临时文件的目录。 ServletFileUpload upload = new ServletFileUpload(factory); upload.setHeaderEncoding("UTF-8"); //创建一个进度监听器 FileUploadProgressListener progressListener = new FileUploadProgressListener(request); upload.setProgressListener(progressListener); try { List items = upload.parseRequest(request); Iterator itr = items.iterator(); while (itr.hasNext()) { FileItem item = (FileItem) itr.next(); String fileName = item.getName(); long fileSize = item.getSize(); if (!item.isFormField()) { //检查文件大小 if(item.getSize() > maxSize){ setStatusMsg(request, "1", "上传文件大小超过限制。"); return; } //检查扩展名 String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); if(!Arrays.<String>asList(extMap.get(dirName).split(",")).contains(fileExt)){ setStatusMsg(request, "1", "上传文件扩展名是不允许的扩展名。只允许" + extMap.get(dirName) + "格式。"); return; } SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); String newFileName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt; try{ File uploadedFile = new File(savePath, newFileName); /* * 第一种方法 * * 好处: 一目了然..简单啊... * 弊端: 这种方法会导致上传的文件大小比原来的文件要大 * * 推荐使用第二种 */ //item.write(uploadedFile); //-------------------------------------------------------------------- //第二种方法 OutputStream os = new FileOutputStream(uploadedFile); InputStream is = item.getInputStream(); byte buf[] = new byte[1024];//可以修改 1024 以提高读取速度 int length = 0; while( (length = is.read(buf)) > 0 ){ os.write(buf, 0, length); } //关闭流 os.flush(); os.close(); is.close(); }catch(Exception e){ setStatusMsg(request, "1", "上传文件失败。"); return; } setStatusMsg(request, "2", "文件上传成功!"); } } } catch (FileUploadException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * * 错误信息的处理 * * @param request * @param error -- 1 : 错误 0 : 正常 2 : 上传完成 * @param message */ private void setStatusMsg(HttpServletRequest request, String error, String message) { HttpSession session = request.getSession(); FileUploadStatus status = (FileUploadStatus) session.getAttribute("upladeStatus"); status.setError(error); status.setStatusMsg(message); } /** * * 获取状态信息 * * @param request * @param out */ @SuppressWarnings("unused") private void getStatusMsg(HttpServletRequest request,PrintWriter out){ HttpSession session = request.getSession(); FileUploadStatus status = (FileUploadStatus) session.getAttribute("upladeStatus"); System.out.println("输出信息对象:"+status); out.println(status.toJSon()); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); //检查输入请求是否为multipart表单数据。 boolean isMultipart= FileUpload.isMultipartContent(request); if (isMultipart) { processFileUpload(request, out); }else { if (request.getParameter("uploadStatus") != null) { //response.setContentType("text/xml"); //response.setHeader("Cache-Control", "no-cache"); System.out.println("ajax 读取状态····"); getStatusMsg(request, out); } } out.flush(); out.close(); } }
FileUploadProgressListener------使用ProgressListener监听文件状态
package com.yangpan.upload.progressbar; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.commons.fileupload.ProgressListener; /** * 上传监听器 * * @author 妞见妞爱 * */ public class FileUploadProgressListener implements ProgressListener { private HttpSession session; private long megaBytes = -1; public FileUploadProgressListener(HttpServletRequest request) { session = request.getSession(); FileUploadStatus newUploadStatus = new FileUploadStatus(); session.setAttribute("upladeStatus", newUploadStatus); } /** * * 为了进度条监听器不会引起性能问题 * 解决方案,是减少进步条的活动数 * 比如,只有当上传了1兆字节的时候才反馈给用户 * */ public void update(long pBytesRead, long pContentLength, int pItems) { /*long mBytes = pBytesRead / 1048576; if (megaBytes == mBytes) { return; } megaBytes = mBytes;*/ FileUploadStatus status = (FileUploadStatus) session.getAttribute("upladeStatus"); if (pContentLength == -1) { status.setStatusMsg("已完成" + pItems +"个文件的上传"); }else { status.setStatusMsg("正在上传第" + pItems +"个文件"); } status.setError("0"); status.setReadedBytes(pBytesRead); status.setTotalBytes(pContentLength); status.setCurrentItem(pItems); } }
FileUploadStatus------使用session保存文件的状态
package com.yangpan.upload.progressbar; /** * * 上传状态类 * * @author 妞见妞爱 * */ public class FileUploadStatus { private String statusMsg = ""; private long readedBytes = 0L; private long totalBytes = 0L; private int currentItem = 0; // 1 : 错误 0 : 正常 2:完成 private String error = "0"; public String getStatusMsg() { return statusMsg; } public void setStatusMsg(String statusMsg) { this.statusMsg = statusMsg; } public long getReadedBytes() { return readedBytes; } public void setReadedBytes(long readedBytes) { this.readedBytes = readedBytes; } public long getTotalBytes() { return totalBytes; } public void setTotalBytes(long totalBytes) { this.totalBytes = totalBytes; } public int getCurrentItem() { return currentItem; } public void setCurrentItem(int currentItem) { this.currentItem = currentItem; } public String getError() { return error; } public void setError(String error) { this.error = error; } public String toJSon() { StringBuffer strJSon = new StringBuffer(); strJSon.append("{"); strJSon.append("error:'").append(error).append("',"); strJSon.append("statusMsg:'").append(statusMsg).append("',"); strJSon.append("readedBytes:'").append(readedBytes).append("',"); strJSon.append("totalBytes:'").append(totalBytes).append("',"); strJSon.append("currentItem:'").append(currentItem).append("'"); strJSon.append("}"); return strJSon.toString(); } }
web.xml
<servlet> <servlet-name>UploadFileProgressBar</servlet-name> <servlet-class> com.yangpan.upload.progressbar.UploadFileProgressBar </servlet-class> </servlet> <servlet-mapping> <servlet-name>UploadFileProgressBar</servlet-name> <url-pattern>/servlet/UploadFileProgressBar</url-pattern> </servlet-mapping>
客户端代码:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %> <% String path = request.getContextPath(); %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>妞见妞爱 QQ:609865047</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <link rel="stylesheet" href="css/jquery-ui-1.8.16.custom.css" type="text/css"></link> <link rel="stylesheet" href="css/main.css" type="text/css"></link> <script type="text/javascript" src="js/jquery-1.6.2.min.js" ></script> <script type="text/javascript" src="js/jquery-ui-1.8.16.custom.min.js" ></script> <script type="text/javascript" src="js/script.js" ></script> <script type="text/javascript"> function uploadFile(){ var file = document.getElementById("file").value; if(file == ""){ alert("请选项上传文件!"); return false; } document.getElementById("editForm").submit(); document.getElementById("updateButton").disabled = "disabled"; ajaxBackState(); } var bool = true; var readedBytes = 0; var totalBytes = 0; function ajaxBackState(){ $.post("<%=path%>/servlet/UploadFileProgressBar",{uploadStatus:"uploadStatus"},function(result){ var obj = eval("("+result+")"); var txt = document.getElementById("txt"); readedBytes = obj["readedBytes"]; totalBytes = obj["totalBytes"]; if(obj["error"] == "0"){ txt.innerHTML = obj["statusMsg"]+":"+ readedBytes +"/"+totalBytes; }else if(obj["error"] == "1"){ txt.innerHTML = obj["statusMsg"]; bool = false; }else{ txt.innerHTML = obj["statusMsg"]+":"+ readedBytes +"/"+totalBytes; bool = false; } }); document.getElementById("bytes").innerHTML += readedBytes + "<br>"; progressbar(readedBytes,totalBytes) if(bool){ setTimeout("ajaxBackState()",1000); } } function progressbar(readedBytes,totalBytes){ $('#progress').children('.pbar').progressbar(); iPerc = (readedBytes > 0) ? (readedBytes / totalBytes) * 100 : 0; // percentages $('#progress').children('.percent').html('<b>'+iPerc.toFixed(1)+'%</b>'); $('#progress').children('.pbar').children('.ui-progressbar-value').css('width', iPerc+'%'); if (iPerc >= 100) { $('#progress').children('.percent').html('<b>100%</b>'); $('#progress').children('.elapsed').html('Finished'); } } /*** * * var readedBytes = 0; var totalBytes = 100000; function test(){ readedBytes = readedBytes + 1000; progressbar(readedBytes,totalBytes); if(readedBytes >= totalBytes){ clearInterval(intervalProcess); } } var intervalProcess = setInterval("test()",1000); **/ </script> </head> <body> <iframe name="uploadIfr" style="display:none;"></iframe> <form id="editForm" action="<%=path%>/servlet/UploadFileProgressBar" method="post" enctype="multipart/form-data" target="uploadIfr" > <input type="file" id="file" name="file" style="width: 300px;" > <input type="button" style="height:20px;" id="updateButton" value=" 上 传 " onclick="uploadFile()" ><br> <span id='txt' ></span><br><br> <div id="progress" style="width: 400px" > <div class="percent"></div> <div class="pbar"></div> <div class="elapsed"></div> </div> <span id=bytes ></span><br> </form> </body> </html>
三、总结
疑惑一:
监听器不会引起性能问题,因为它是实时的。我看有些文档上面有说可能会。我暂时把它注释掉了。
扩展:
1、上传成功后。点击删除按钮删除上传文件---这个倒简单
2、上传中。点击取消上传,---这个如何实现? 希望大家讨论下...是不是可以直接关闭什么输入输出流来实现?
O(∩_∩)O哈哈~..差不多了...说的差不多了,希望它多少能为您的工作或学习带来点儿帮助。
相关推荐
为了提供更好的用户体验,引入了Ajax文件上传和进度条功能。这个话题主要涵盖了如何使用jQuery库和Apache的FileUpload组件来创建一个动态的、实时显示上传进度的界面。 **jQuery** 是一个流行的JavaScript库,它...
比如带进度条的文件上传,看了网上很多资料还没找到真正意义上的ASP.NET实现进度条上传.Ajax 文件上传进度条,ASP.NET 文件上传进度条示例,ASP.NET 文件上传,asp.net文件上传,ajax文件上传.源码示例
它利用Ajax技术,使得文件上传无需刷新页面即可完成。这极大地提升了用户体验,因为用户可以在上传文件的同时继续浏览其他内容。 3. **上传进度条**: 上传进度条是用户界面中显示文件上传状态的元素,它通常以...
结合进度条展示,可以提供更优秀的用户体验,让用户清晰地看到文件上传的进度,消除等待的不确定感。 首先,要实现Ajax无刷新上传文件,我们需要了解XMLHttpRequest对象,这是Ajax的核心组件。通过创建...
Ajax技术的出现为解决这一问题提供了可能,它允许我们在不刷新整个页面的情况下进行异步通信,从而实现文件上传进度条的功能。下面将详细讲解如何利用Ajax实现文件上传进度条。 首先,我们需要理解Ajax的基本原理。...
总的来说,"struts2+ajax文件进度条的实现"是一个典型的前后端协同工作的示例,它展示了如何在Java web应用中优化用户体验,特别是在处理大文件上传时。通过理解Ajax的工作原理、Struts2的文件上传机制以及前端组件...
Layui实现文件上传进度条 Layui是一个优秀的前端框架...通过使用Layui的进度条组件和AjaxUpload组件,我们可以轻松地实现文件上传进度条。使用Layui可以让我们快速构建Web应用程序,并提供了很多实用的UI组件和功能。
在这个项目中,SSH2框架与Ajax技术结合,实现了一个带进度条的文件上传功能,并且这个功能已经被封装成了自定义标签,方便在页面上直接使用。 首先,让我们深入理解SSH框架的每个组件: 1. **Struts2**:Struts2是...
在文件上传场景中,传统的表单提交方式会刷新整个页面,导致用户体验不佳。而Ajax上传则能实现无刷新上传,通过XMLHttpRequest对象发送异步请求,保持页面状态不变。 1. 原理: Ajax上传文件时,浏览器将文件分块...
总结来说,"jquery ajax上传 带进度条"涉及到使用jQuery和Uploadify插件实现文件上传功能,并通过AJAX实时更新上传进度条,从而提供一个友好的用户界面。服务器端的处理同样重要,需要接收文件并给予适当的响应。...
总结,通过Ajax与SpringMVC的结合,我们可以实现文件上传过程中前端的进度条显示。关键在于利用Ajax的异步特性,监听文件上传的进度,并通过自定义后端组件将这些信息传递回前端。这样的设计不仅提升了用户体验,也...
实现Ajax文件上传进度条,我们需要以下几个关键步骤: 1. **HTML表单设计**:创建一个包含文件输入控件的表单,通常还需要一个按钮来触发上传操作。例如: ```html 上传 ``` 2. **JavaScript事件监听**:绑定...
AJAXFileUpload是一种基于AJAX技术的异步文件上传组件,它允许用户在不刷新页面的情况下上传文件,并且可以实时显示上传进度,提供良好的用户体验。本文将深入探讨AJAXFileUpload的工作原理、实现方式以及其在实际...
在JavaScript中实现文件上传进度条是一项重要的用户交互优化工作,它可以显著提升用户体验,尤其是在处理大文件上传时。本文将深入探讨如何实现这一功能,主要涉及以下几个关键知识点: 1. **进度条的实现**:...
在本文中,我们使用jquery的ajax方法来实现文件上传,并且使用jquery-ui库来实现进度条的显示。 知识点2:使用ASP.NET缓存机制实现文件上传进度条显示 在本文中,我们使用ASP.NET缓存机制来实现文件上传进度条的...
标题 "ssh2(struts2+spring2.5+hibernate3.3+ajax)带进度条文件上传(封装成标签)" 涉及到的是一个基于Java Web的项目,利用了Struts2、Spring2.5、Hibernate3.3和Ajax技术,实现了文件上传并带有进度条显示的功能...
对于文件上传,Ajax可以发送二进制数据,使得在后台处理文件上传的同时,用户仍能在前台进行其他操作。 要实现带进度条的Ajax上传,关键在于HTML5的File API和ProgressEvent接口。File API允许我们直接访问和操作...
在文件上传进度条的实现中,AJAX被用来异步获取服务器端上传进度信息,并实时更新页面上的进度条显示,从而提供更流畅的用户体验。 ### 实现步骤 #### 步骤一:创建UploadProgressMeter类 首先,需要创建一个`...
在带进度条的文件上传中,Ajax起到了关键作用。前端通过Ajax发送文件数据,可以避免整个页面刷新,保持用户的交互界面不中断。在Ajax请求中,我们通常会使用XMLHttpRequest对象,通过设置onprogress事件监听上传进度...
1. **Ajax文件上传**:传统的文件上传方式通常会刷新整个页面,用户体验不佳。Ajax(Asynchronous JavaScript and XML)技术允许我们在后台与服务器进行通信,不刷新页面即可完成文件上传。通过XMLHttpRequest对象...