请客官参考http://blog.itpub.net/30066956/viewspace-1775286/ 这一篇文章,来决定使用哪儿种,个人觉得使用uploadify更好更方便。

感谢:http://blog.sina.com.cn/s/blog_674b23220100he8x.html ,本文参考了很多这篇博文中的内容。
摘要:

         在web项目中,经常会有文件上传需求。有时会遇到上传很大的文件,需要时间比较长。这样如果在界面上给用户一个进度条展示上传进度,会大大增加用户使用的方便。

struts进行文件上传时,前台进度显示的一种解决方案。

 

Struts2  进度条  文件上传 progressbar  easyui

 

2G,实际用户上传的数据文件大小一般也不会太小,再加上如果网速慢的话,等待时间可能会很长。所以要为这个功能加上进度条,让用户在等待过程中, 了解自己数据上传进度。

先上效果图

       

解决步骤。

1、  前台进度条控件选择使用easyui 的progressbar控件。

详细的使用说明参考官网文档:http://www.jeasyui.com/documentation/index.php

所有需要引入jquery-1.11.1.min.js 以及jquery.easyui.min.js

2、 前台显示控件有了,下面需要提供一个后台方法,来供前台查询上传进度。(使用Struts2自带的文件上传,它集成了commons-fileupload)

3、 在上传文件时,不断的向后台请求目前的进度,改变进度条控件的值。

实现监控到文件上传进度

下面的重点在于如何使用commons-fileupload进行文件上传时使用进度。

http://commons.apache.org/proper/commons-fileupload/using.html 在这个官方文档中搜索 Watching progress 可以得到详细的指导。



点击(此处)折叠或打开


1.  //Create a progress listener
2.  ProgressListener progressListener = new ProgressListener(){
3.     public void update(long pBytesRead, long pContentLength, int pItems) {
4.         System.out.println(“We are currently reading item “ + pItems);
5.         if (pContentLength == -1) {
6.             System.out.println(“So far, “ + pBytesRead + ” bytes have been read.”);
7.         } else {
8.             System.out.println(“So far, “ + pBytesRead + ” of “ + pContentLength
9.                                + ” bytes have been read.”);
10.         }
11.     }
12.  };
13.  upload.setProgressListener(progressListener);


先创建一个实现了ProgressListener接口的对象,然后对upload对象发出增加监听器消息。

但问题是,我们是使用了Struts2 进行文件上传。而Struts2在文件上传的处理的类过程中并没有为我们加一个这样的监听器。

解决办法:(参考http://blog.sina.com.cn/s/blog_674b23220100he8x.html)

找到org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest类的代码。

自己写个类实现MyMultiPartRequest把

org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest的代码copy进来再修改parseRequest 这个方法的实现,加上监听部分。把进度信息放到Session中 
   
 这是我的项目中修改后的parseRequest方法。 

 
 
 点击(此处)折叠或打开 
 
  
1.  private List<FileItem> parseRequest(HttpServletRequest servletRequest,
2.              String saveDir) throws FileUploadException {
3.  
4.          UploadStatus status = new UploadStatus(); // 上传状态
5.          UploadListener listner = new UploadListener(status); // 监听器
6.          servletRequest.getSession().setAttribute(“uploadStatus”, status); // 把状态放到session里去
7.  
8.          DiskFileItemFactory fac = createDiskFileItemFactory(saveDir);
9.          ServletFileUpload upload = new ServletFileUpload(fac);
10.          upload.setSizeMax(maxSize);
11.          upload.setProgressListener(listner);// 添加监听器
12.  
13.          return upload.parseRequest(createRequestContext(servletRequest));
14.      }







点击(此处)折叠或打开



  1. public class UploadListener implements ProgressListener {
  2.     private UploadStatus status;
  3.     public UploadListener(UploadStatus status) {
  4.         this.status = status;
  5.     }
  6.     public void update(long bytesRead, long contentLength, int items) {
  7.         // 上传组件会调用该方法
  8.         status.setBytesRead(bytesRead); // 已读取的数据长度
  9.         status.setContentLength(contentLength); // 文件总长度
  10.         status.setItems(items); // 正在保存第几个文件
  11.         
  12.     }
  13. }






点击(此处)折叠或打开


1.  public class UploadStatus {
2.  
3.      private long bytesRead; // 已经上传的字节数,单位:字节
4.      private long contentLength; // 所有文件的总长度,单位:字节
5.      private int items; // 正在上传第几个文件
6.      private long startTime = System.currentTimeMillis(); // 开始上传的时间,用于计算上传速度等
7.      public long getBytesRead() {
8.          return bytesRead;
9.      }
10.      public void setBytesRead(long bytesRead) {
11.          this.bytesRead = bytesRead;
12.      }
13.      public long getContentLength() {
14.          return contentLength;
15.      }
16.      public void setContentLength(long contentLength) {
17.          this.contentLength = contentLength;
18.      }
19.      public int getItems() {
20.          return items;
21.      }
22.      public void setItems(int items) {
23.          this.items = items;
24.      }
25.      public long getStartTime() {
26.          return startTime;
27.      }
28.      public void setStartTime(long startTime) {
29.          this.startTime = startTime;
30.      }
31.      
32.  } 
 
 

 还需要配置一下,让Struts2使用我们自己写的MyMultiPartRequest


点击(此处)折叠或打开


1.  <constant name=“struts.multipart.parser” value=“com.hengyun.action.uploadprocess.MyMultiPartRequest” />
2.  <constant name=“struts.multipart.handler” value=“com.hengyun.action.uploadprocess.MyMultiPartRequest” />
3.  <constant name=“struts.multipart.maxSize” value=“2000000000”/>

取得进度信息

经过上面的工作,现在在上传文件时,Session已经有了UploadStatus 对象了。

可以实现一个action,从Session中取进度信息,返回前台。

项目中action 代码,可以用做参考




点击(此处)折叠或打开



    1.  /**
    2.       * 显示文件上传的进度
    3.       */
    4.      public String getFileUploadProgress(){
    5.          ActionContext cxt = ActionContext.getContext(); 
    6.          HttpServletResponse response = (HttpServletResponse)cxt.get(ServletActionContext.HTTP_RESPONSE);
    7.           
    8.          UploadStatus status = (UploadStatus)SessionUtil.getObjectFromSession(“uploadStatus”);
    9.          
    10.          if(status == null){
    11.              return “fail”;
    12.          }
    13.          
    14.          long startTime = status.getStartTime(); //上传开始时间
    15.          long currentTime = System.currentTimeMillis(); //现在时间
    16.          long time = (currentTime - startTime)/ 1000 + 1; //已传输的时间 单位:s
    17.          
    18.          //传输速度单位:byte/s
    19.          double velocity = ((double)status.getBytesRead()) / (double)time;
    20.          //估计总时间
    21.          double totalTime = status.getContentLength();
    22.          //估计剩余时间
    23.          double timeLeft = totalTime - time;
    24.          //已经完成的百分比
    25.          int percent = (int)(100 * (double)status.getBytesRead() / (double)status.getContentLength());
    26.          //已经完成数单位:m
    27.          double length = ((double) status.getBytesRead())/1024/1024;
    28.          //总长度 单位:m
    29.          double totalLength = ((double) status.getContentLength())/1024/1024; 
    30.          
    31.          ret.put(“percent”, String.valueOf(percent));
    32.          ret.put(“length”, String.valueOf(length));
    33.          ret.put(“totalLength”,String.valueOf( totalLength));
    34.          ret.put(“velocity”, String.valueOf(velocity));
    35.          ret.put(“time”, String.valueOf(time));
    36.          ret.put(“totalTime”, String.valueOf(totalTime));
    37.          ret.put(“timeLeft”, String.valueOf(timeLeft));
    38.          ret.put(“fileNumber”, String.valueOf(status.getItems()));
    39.          return “success”;
    40.  }

    demo贴上来,以供参考吧。



    点击(此处)折叠或打开


    1.  <%@ page language=“java” import=“java.util.*” pageEncoding=“UTF-8”%>
    2.  <%
    3.  String path = request.getContextPath();
    4.  String basePath = request.getScheme()+“://”+request.getServerName()+“:”+request.getServerPort()+path+“/”;
    5.  %>
    6.  
    7.  <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
    8.  <html>
    9.   <style type=“text/css”>
    10.   #progressBar{width:400px;height:12px;background:#FFFFFF;border:1px solid #000000; padding: 1px;}
    11.   #progressBarItem{width:0%; height:100%;background:#FF0000}
    12.   </style>
    13.   <link rel=“stylesheet” type=“text/css” href=“css/easyui.css”>
    14.   <link rel=“stylesheet” type=“text/css” href=“css/demo.css”>
    15.   <link rel=“stylesheet” type=“text/css” href=“css/icon.css”>
    16.   
    17.  
    18.   <script type=“text/javascript” src=“js/jquery-1.11.1.min.js”></script>
    19.   <script type=“text/javascript” src=“js/jquery.easyui.min.js”></script>
    20.   <script type=“text/javascript” src=“js/json/json_parse_state.js”></script>
    21.    <script type=“text/javascript” src=“js/main.js”></script>
    22.   
    23.   
    24.   
    25.   
    26.   <script>
    27.           function showUploadProgress(processbarid){
    28.              var url =‘test/test_doFileProgress.action?radom=’+Math.random();
    29.              var dataObj = $.ajax({
    30.                      url : url,
    31.                      async : false
    32.              });
    33.      
    34.              var myObject = json_parse(dataObj.responseText);
    35.              $(“[id=”+processbarid+“]”).progressbar(‘setValue’, myObject.percent);
    36.              setTimeout(arguments.callee, 500);
    37.          };
    38.          
    39.          function uploadData() {
    40.              showUploadProcess(“fileuploadprocessbar”)
    41.              $(‘#uploadData’).form(‘submit’, {
    42.                  url : ‘data/dataAction_saveData.action’,
    43.                  success : function(data) {
    44.                          $(‘#uploadData’).form(‘clear’);
    45.                  }
    46.              });
    47.          }
    48.  </script>
    49.   </head>
    50.     <body>
    51.          <form id=“uploadData” method=“post” action=“data/dataAction_saveData.action” enctype=“multipart/form-data”“>
    52.          
    53.          <div class=”content“>
    54.             <table border=”0” cellspacing=”1” cellpadding=”0” width=”100%” class=”tk_table“>
    55.                <tr>
    56.                  <td>文件上传:</td>
    57.                  <td><input type=”file” name=”file” size=”28” /></td>
    58.                </tr>
    59.                <tr>
    60.                <td>进度<td/> 
    61.                <td><div id=”fileuploadprocessbar” class=”easyui-progressbar” style=”width:400px;background-color:‘ff0000’“></div> </td>
    62.                 </tr>
    63.             </table>
    64.          </div>
    65.          <div class=”bottombtn“>
    66.              <table width=”40%” class=”btntalbe“>
    67.                  <tr>
    68.                      <td align=”center“>
    69.                          <input id=”btnOk” type=”submit” value=”确定” class=”tkbtn surebt” οnclick=”uploadData()“/></td>
    70.                      <td align=”center“>
    71.                          <input type=”button” class=”closeB tkbtn” value=”取消 
     
     
    
    only one.它就是 : 
             showUploadProgress(processbarid); 
         processbarid 为前台processbar 控件的id。