servlet多文件上传(带进度条)

需要commons-fileupload-1.3.jar和commons-io-2.4.jar的支持

页面效果:(图片文件都可以)

(1)进度标识类

public class UploadStatus {
    private long bytesRead;
    private long contentLength;
    private int items;
    private long startTime = System.currentTimeMillis();
    //set get 方法 省略
}

(2)监听器

import org.apache.commons.fileupload.ProgressListener;
public class UploadListener implements ProgressListener {
	private UploadStatus status;
	//构造方法
	public UploadListener(UploadStatus status) {
		super();
		this.status = status;
	}
      //重写方法
	public void update(long bytesRead, long contentLength, int items) {
		status.setBytesRead(bytesRead);
		status.setContentLength(contentLength);
		status.setItems(items);
	}
}

(3)action类(FileItem类是common中的方法)

public class UploadServlet extends HttpServlet {

    //定义临时文件盒上传文件的存储路径
    private File uploadTemp=null;
    private File uploadPath=null; 

  public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

	//禁用缓存,index.jsp后台会使用XmlHttpRequest调用本Servlet的doGet方法,从session中获取最新的上传数据情况
        response.setHeader("Cache-Control", "no-store");
        response.setHeader("Pragrma", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("text/html;charset=utf-8");
        UploadStatus status = (UploadStatus) request.getSession(true)
                .getAttribute("uploadStatus");  

        if (status == null) {
            response.getWriter().println("没有上传信息");  

            return;
        }
        long startTime = status.getStartTime();
        long currentTime = System.currentTimeMillis();  

        // 已传输的时间 单位:s
        long time = (currentTime - startTime) / 1000 + 1;  

        // 传输速度 单位:byte/s
        double velocity = ((double) status.getBytesRead()) / (double) time;  

        // 估计总时间 单位:s
        double totalTime = status.getContentLength() / velocity;  

        // 估计剩余时间 单位:s
        double timeLeft = totalTime - time;  

        // 已完成的百分比
        int percent = (int) (100 * (double) status.getBytesRead() / (double) status
                .getContentLength());  

        // 已完成数 单位:M
        double length = ((double) status.getBytesRead()) / 1024 / 1024;  

        // 总长度 单位:M
        double totalLength = ((double) status.getContentLength()) / 1024 / 1024;  

        // 格式:百分比||已完成数(M)||文件总长度(M)||传输速率(K)||已用时间(s)||估计总时间(s)||估计剩余时间(s)||正在上传第几个文件
        String value = percent + "||" + length + "||" + totalLength + "||"
                + velocity + "||" + time + "||" + totalTime + "||" + timeLeft
                + "||" + status.getItems();  

        response.getWriter().println(value);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		File file=null;
        String description=null;  

        //设置响应格式(不设置请求格式,因为文件是二进制的,不能使用UTF-8格式化请求数据)
        response.setContentType("text/html;charset=utf-8");  

        PrintWriter out=response.getWriter();
        out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
        out.println("<HTML>");
        out.println("<HEAD><TITLE>文件上传</TITLE></HEAD>");
        out.println("<BODY style=‘margin:50px‘>");
        out.println("上传日志:<BR/>");  

        UploadStatus status=new UploadStatus();
        UploadListener listener=new UploadListener(status);
        /*
         * 把 UploadStatus 放到 session 里,引用
		 * 返回与此请求关联的当前HttpSession,如果没有当前会话和创造是真实的,返回一个新的会话。
		 * 如果创建是假的,并要求有没有有效的HttpSession,这个方法返回null。
         */
        request.getSession(true).setAttribute("uploadStatus", status);  

        //创建基于磁盘的工厂,针对大文件,临时文件将存储在磁盘
        DiskFileItemFactory factory=new DiskFileItemFactory();
        //设置缓冲区大小,超出该文件直接写入到磁盘的大小设置门槛。
        factory.setSizeThreshold(10240);  //这里默认10KB
        //设置用于大于配置的大小阈值设置的临时存储文件目录。
        factory.setRepository(uploadTemp);
        //创建一个文件上传的句柄
        ServletFileUpload upload=new ServletFileUpload(factory);
        //设置最大文件尺寸 ,这里是40MB
        upload.setSizeMax(41943040);
        upload.setHeaderEncoding("utf-8");  

        // 设置 listener
        upload.setProgressListener(listener);  

        try {
            //将解析结果放在LIST中
            List<FileItem> list =upload.parseRequest(request);
            out.println("遍历所有的 FileItem ... <br/>");
            // 遍历 list 中所有的 FileItem
            for(FileItem item:list)
            {
                // 如果是 文本域
                if(item.isFormField())
                {
                    if(item.getFieldName().equals("description1")||item.getFieldName().equals("description2"))
                    {  

                        description = item.getString("UTF-8");
                        System.out.println("文件名: "+item.getFieldName()+" ----描述-------"+description);
                    }
                }
                else
                {
                    //否则为文件域,当getName为Null说明没有选则文件
                    if((item.getFieldName().equals("file1")||item.getFieldName().equals("file2"))
                            &&item.getName()!=null&&!item.getName().equals(""))
                    {
                        try
                        {
                            // 统一 Linux 与 windows 的路径分隔符
                            String fileName = item.getName();
                            //fileName = fileName.substring(fileName.lastIndexOf("\\"));  

                            // 服务器端文件,放在 upload 文件夹下
                            file=new File(uploadPath,fileName);
                            if(!file.getParentFile().exists())
                                file.getParentFile().mkdirs();
                            if(!file.exists())
                                file.createNewFile();  

                            item.write(file);  

                            System.out.println("遍历到 "+fileName+" ... <br/>"+description+"<BR/>");
                        } catch (Exception e) {
                            System.out.println("Request 上传失败!"+e.getMessage());
                        }
                        finally //总是立即删除保存表单字段内容的临时文件
                        {
                            item.delete();
                        }
                    }
                }
            }
            System.out.println("Request 解析完毕,文件上传完毕!");
        } catch (Exception e) {
            System.out.println("Request 解析异常!"+e.getMessage());
        }
        out.flush();
        out.close();
	}

	/**
	 * Initialization of the servlet. <br>
	 *
	 * @throws ServletException if an error occurs
	 */
	public void init() throws ServletException {
		// Put your code here
		uploadPath=new File(this.getServletContext().getRealPath("upload"));
        if(!uploadPath.exists())
            uploadPath.mkdirs();
        uploadTemp=new File(this.getServletContext().getRealPath("upload/temp"));
        if(!uploadTemp.exists())
            uploadTemp.mkdirs();
	}

}

(4)index.jsp页面

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
 <title>带进度条的文件上传</title>
 <style type="text/css">
	 #progressBar{width:400px;height:12px;background:#FFFFFF;border:1px solid #000000;padding:1px;}
	 #progressBarItem{width:30%;height:100%;background:#FF0000;}
 </style>
 <script type="text/JavaScript">
 //默认为已经完成上传操作
 var _finished=true;
 function $(obj)
 {
 return document.getElementById(obj);
 }
 //<!--显示进度条等信息-->
 function showStatus()
 {
 _finished=false;
 $(‘status‘).style.display=‘block‘;
 $(‘progressBarItem‘).style.width=‘1%‘;
 $(‘btnSubmit‘).disabled=true;
 //<!--隔1秒后执行一次-->
 setTimeout("requestStatus()",1000);
 }
 //<!--发送请求获取文件上传状态-->
 function requestStatus()
 {
 if(_finished)
 return;
 var req=createRequest();
 req.open("GET","servlet/UploadServlet");
 req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
 req.onreadystatechange=function(){callback(req);};
 //我们的实例在 open() 的第三个参数中使用了 "true"。该参数规定请求是否异步处理。
 //True 表示脚本会在 send() 方法之后继续执行,而不等待来自服务器的响应。

 req.send(null);
 setTimeout("requestStatus()",1000);
 }
 function createRequest()
 {
  if(window.XMLHttpRequest)//ns
  {
   return new XMLHttpRequest();
  }else//IE
  {
   try{
    return new ActiveXObject("Msxml2.XMLHTTP");
   }catch(e){
    return new ActiveXObject("Microsoft.XMLHTTP");
   }
  }
  return null;
 }
 function callback(req)
 {
   //请求结束后
 if(req.readyState==4)
 {
  //如果发生错误,则显示错误信息
 if(req.status!=200)
 {
 _debug("发生错误。 req.status: " + req.status + "");
    return;
 }

   var ss = req.responseText.split("||");

   // 格式:百分比||已完成数(M)||文件总长度(M)||传输速率(K)||已用时间(s)||估计总时间(s)||估计剩余时间(s)||正在上传第几个文件
   $(‘progressBarItem‘).style.width = ‘‘ + ss[0] + ‘%‘;
   $(‘statusInfo‘).innerHTML = ‘已完成百分比: ‘ + ss[0] + ‘% <br />已完成数(M): ‘ + ss[1] + ‘<br/>文件总长度(M): ‘ + ss[2] + ‘<br/>传输速率(K): ‘ + ss[3] + ‘<br/>已用时间(s): ‘ + ss[4] + ‘<br/>估计总时间(s): ‘ + ss[5] + ‘<br/>估计剩余时间(s): ‘ + ss[6] + ‘<br/>正在上传第几个文件: ‘ + ss[7];

   if(ss[1] == ss[2])
 {
   _finished = true;
   $(‘statusInfo‘).innerHTML += "<br/><br/><br/>上传已完成。";
   $(‘btnSubmit‘).disabled = false;
   }
   _debug("status.jsp 返回值:" + req.responseText);

 }
 }
 function _debug(obj)
 {
 //var div=document.createElement("DIV");
 $(‘debug‘).innerHTML="[debug]:"+obj+"<br/>";
 //document.body.appendChild(div);

 }
 </script>
 </head>
 <body style="margin:50px">
 <iframe name="upload_iframe" width="0" height="0" frameborder="0" ></iframe>

  <form action="servlet/UploadServlet" method="post" enctype="multipart/form-data"
  target="upload_iframe" onsubmit="showStatus();">
  <p>上传文件:</p>
	  文件1:<input type="file" name="file1" /><br/>
	  描述:<input type="text" name="description1" /><br/>
	  文件2:<input type="file" name="file2" /><br/>
	  描述:<input type="text" name="description2" /><br/>
  <input type="submit" id="btnSubmit" value=" 上 传 " />
  </form>
  <div id="status" style="display:none;position:relative;line-height:100%;opacity:1;">
  上传进度:
  <div id="progressBar" ><div id="progressBarItem" /></div>
  <div id="statusInfo" style="margin:10px 0px 0px 0px;"/>
  </div>
  <BR/>
  <div id="debug" />
 </body>
 </html>

  资源代码下载:http://download.csdn.net/detail/u011518709/8179663

  

  

  

时间: 2024-11-07 23:30:52

servlet多文件上传(带进度条)的相关文章

atitit. 文件上传带进度条 atiUP 设计 java c# php

atitit. 文件上传带进度条 atiUP 设计 java c# php 1. 设计要求 1 2. 原理and 架构 1 3. ui 2 4. spring mvc 2 5. springMVC.xml 3 6. struts extand url 3 7. behide code 3 8. 简化设计 3 1. 设计要求 带进度条 完成提示动画效果.. 2. 原理and 架构 如果需要显示进度条,实时显示文件上传进度 需要使用Ajaxj技术..up到个在的iframe黑头.. 工作原理 其实际

atitit.文件上传带进度条的实现原理and组件选型and最佳实践总结O7

1. 实现原理 1 2. 大的文件上传原理::使用applet 1 3. 新的bp 2 1. 性能提升---分割小文件上传,避免一次使用内存使用过大的 2 2. Uuid还是原来文件名称:: 2 3. 监听器频繁地被调用 2 4. 结合wz easyui 2 4. 选型 2 5. Uploadify::yash js+flash 3 6. commons-fileupload:: 3 7. COS这个工具O'Reilly公司 3 8. 大的文件上传组件总结 3 5. 林吧实现ui Ajax+jq

Struts2文件上传带进度条,虽然不是很完美

好久没有写东西,最近在做个项目,要用到文件h 传的,以前虽然也做上传,但是总觉得不好用 ,现在和队友合作做了一个带进度条的上传,觉得还行~~和大家分享一下. 首先说一下大概是这样实现的,在我们平时的上传表单里面,除了文件上传之外,也许还有其他的信息需要填写的,这样问题就来了:点击上传按钮之后,这个表单都封装并提交上去了,在上传完成后整个页面就跳转了.而且也不利于我们验证用户输入.很多人这样做的,把这2个操作分开,当然这样也行... 我们这样做:一个普通页面(可以用于填写所有信息的),一个文件上传

php实现大文件上传带进度条

1.使用PHP的创始人 Rasmus Lerdorf 写的APC扩展模块来实现(http://pecl.php.net/package/apc) APC实现方法: 安装APC,参照官方文档安装,可以使用PECL模块安装方法快速简捷,这里不说明 配置php.ini,设置参数 apc.rfc1867=1 ,使APC支持上传进度条功能,在APC源码说明文档里面有说明 代码范例: 大文件(50G)上传的实现细节: 服务端接收文件数据的处理逻辑代码: 2.使用PECL扩展模块uploadprogress实

HTML5 + AJAX ( jQuery版本 ) 文件上传带进度条

页面技术:HTML5 + AJAX ( jQuery) 后台技术:Servlet 3.0 jQuery版本:1.9.1 后台Servlet代码这里就省略了,使用的是 AJAX请求遭遇未登录和Session失效的解决方案 这篇文章里面的后台Servlet.所以这里只看前台的JS代码. 首先HTML5用AJAX提交数据先要学习一个HTML5新增加的对象:FormData  FormData 对象可以使用append 方法进行 key - value的数据添加,与以前我们常用的json不同的就是可以异

html5 文件上传 带进度条

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <ti

asp.net web大文件上传带进度条实例代码

using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.Ht

简单实现一个文件上传的进度条

新手初学web 文件上传做完了 进度做了 没有进度条只有文字 不太好看  需要做个进度条  没有美工 网上很多的 进度条 需要图片 还有各种框架 看着好麻烦 只好自己弄一个 还挺简单的 没想象的那么复杂  分享一下 jsp页面 <tr> <td width="100">图片</td> <td> <div style="width: 450px;"> <div class="file-box&

jQuery.uploadify-----文件上传带进度条,支持多文件上传的插件

借鉴别人总结的uploadify:基于jquery的文件上传插件,支持ajax无刷新上传,多个文件同时上传,上传进行进度显示,控制文件上传大小,删除已上传文件. uploadify有两个版本,一个用flash,一个是html5.html5的需要付费~所以这里只说flash版本的用法. uploadify官网地址:http://www.uploadify.com/ 上传文件截图: uploadify文档:http://www.uploadify.com/documentation/,在这儿可以查看

HTML5多图片拖拽上传带进度条

前言 昨天利用css2的clip属性实现了网页进度条觉得还不错,但是很多情况下,我们在那些时候用进度条呢,一般网页加载的时候如果有需要可以用,那么问题就来了,怎么才算整个加载完毕呢,是页面主要模块加载完毕,还是window.onload之后算呢,对这些方面,我真不敢随意回答,因业务需求而定,本文想要说的是在图片上传的时候用到的进度条. 效果展示 详细参考请移步至html5demo HTML5 新增的拖拽相关事件说明 1.ondragover 效果图演示是所看见的可以将文件不仅仅是图片拖拽到该di