Java web 中实现 文件上传 进度条显示

请客官参考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.         UploadStatus status = new UploadStatus(); // 上传状态
  4.         UploadListener listner = new UploadListener(status); // 监听器
  5.         servletRequest.getSession().setAttribute(“uploadStatus”, status); // 把状态放到session里去

  6.         DiskFileItemFactory fac = createDiskFileItemFactory(saveDir);
  7.         ServletFileUpload upload = new ServletFileUpload(fac);
  8.         upload.setSizeMax(maxSize);
  9.         upload.setProgressListener(listner);// 添加监听器

  10.         return upload.parseRequest(createRequestContext(servletRequest));
  11.     }


UploadListener 类代码


点击(此处)折叠或打开

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


还需要配置一下,让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. <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
  7. <html>
  8.  <style type=“text/css”>
  9.  #progressBar{width:400px;height:12px;background:#FFFFFF;border:1px solid #000000; padding: 1px;}
  10.  #progressBarItem{width:0%; height:100%;background:#FF0000}
  11.  </style>
  12.  <link rel=“stylesheet” type=“text/css” href=“css/easyui.css”>
  13.  <link rel=“stylesheet” type=“text/css” href=“css/demo.css”>
  14.  <link rel=“stylesheet” type=“text/css” href=“css/icon.css”>
  15.  

  16.  <script type=“text/javascript” src=“js/jquery-1.11.1.min.js”></script>
  17.  <script type=“text/javascript” src=“js/jquery.easyui.min.js”></script>
  18.  <script type=“text/javascript” src=“js/json/json_parse_state.js”></script>
  19.   <script type=“text/javascript” src=“js/main.js”></script>
  20.  
  21.  
  22.  
  23.  
  24.  <script>
  25.          function showUploadProgress(processbarid){
  26.             var url =‘test/test_doFileProgress.action?radom=’+Math.random();
  27.             var dataObj = $.ajax({
  28.                     url : url,
  29.                     async : false
  30.             });
  31.     
  32.             var myObject = json_parse(dataObj.responseText);
  33.             $(“[id=”+processbarid+“]”).progressbar(‘setValue’, myObject.percent);
  34.             setTimeout(arguments.callee, 500);
  35.         };
  36.         
  37.         function uploadData() {
  38.             showUploadProcess(“fileuploadprocessbar”)
  39.             $(‘#uploadData’).form(‘submit’, {
  40.                 url : ‘data/dataAction_saveData.action’,
  41.                 success : function(data) {
  42.                         $(‘#uploadData’).form(‘clear’);
  43.                 }
  44.             });
  45.         }
  46. </script>
  47.  </head>
  48.    <body>
  49.         <form id=“uploadData” method=“post” action=“data/dataAction_saveData.action” enctype=“multipart/form-data”“>
  50.         
  51.         <div class=”content“>
  52.            <table border=”0” cellspacing=”1” cellpadding=”0” width=”100%” class=”tk_table“>
  53.               <tr>
  54.                 <td>文件上传:</td>
  55.                 <td><input type=”file” name=”file” size=”28” /></td>
  56.               </tr>
  57.               <tr>
  58.               <td>进度<td/>
  59.               <td><div id=”fileuploadprocessbar” class=”easyui-progressbar” style=”width:400px;background-color:‘ff0000’“></div> </td>
  60.                </tr>
  61.            </table>
  62.         </div>
  63.         <div class=”bottombtn“>
  64.             <table width=”40%” class=”btntalbe“>
  65.                 <tr>
  66.                     <td align=”center“>
  67.                         <input id=”btnOk” type=”submit” value=”确定” class=”tkbtn surebt” οnclick=”uploadData()“/></td>
  68.                     <td align=”center“>
  69.                         <input type=”button” class=”closeB tkbtn” value=”取消



如何使用

    在任何一个需要进度条显示上传文件进度的地方只要在提交之前加一行代码就可以了!only one.它就是 :

        showUploadProgress(processbarid);

    processbarid 为前台processbar 控件的id。



  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Spring Boot使用Ant Design来实现文件上传进度条,你可以按照以下步骤进行操作: 1. 首先,确保你已经在Spring Boot项目引入了Ant Design所需的前端资源。可以通过以下方式引入: - 在HTML文件引入Ant Design的样式文件和脚本文件: ```html <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/antd/dist/antd.css"> <script src="https://cdn.jsdelivr.net/npm/antd/dist/antd.js"></script> ``` - 或者,你也可以通过npm安装Ant Design并将其作为项目的依赖使用。 2. 在Spring Boot编写一个用于处理文件上传的Controller。可以使用`MultipartFile`来接收上传的文件,并使用`@RestController`注解将其声明为一个RESTful接口。 ```java import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; @RestController public class FileUploadController { @PostMapping("/upload") public String handleFileUpload(@RequestParam("file") MultipartFile file) throws IOException { // 处理文件上传的逻辑 // 可以在这里获取文件的输入流并保存到指定位置 // 返回上传成功的消息或其他信息 return "File uploaded successfully"; } } ``` 3. 在前端页面使用Ant Design的组件来实现文件上传进度条。你可以使用`Upload`组件来实现文件上传功能,同时使用`Progress`组件来展示上传进度条。 ```html <template> <div> <Upload action="/upload" :before-upload="beforeUpload" :on-progress="onProgress" :on-success="onSuccess" :on-error="onError" > <a-button type="primary" icon="upload">选择文件</a-button> </Upload> <Progress :percent="uploadPercentage" v-if="showProgressBar" /> </div> </template> ``` 4. 在Vue组件的`data`定义相关变量,并在方法定义上传前和上传过程的回调函数。 ```javascript export default { data() { return { showProgressBar: false, uploadPercentage: 0 } }, methods: { beforeUpload(file) { // 这里可以进行一些文件格式或大小的校验 }, onProgress(event, file) { // 计算上传进度并更新进度条 this.uploadPercentage = Math.round((event.loaded / event.total) * 100); this.showProgressBar = true; }, onSuccess(response, file) { // 上传成功后的处理 // 根据后端返回的数据进行相应的操作 }, onError(error, response, file) { // 上传失败后的处理 } } } ``` 5. 最后,你需要引入Vue和Ant Design的相关组件和样式文件。 ```javascript import Vue from 'vue'; import { Upload, Button, Progress } from 'ant-design-vue'; import 'ant-design-vue/dist/antd.css'; Vue.use(Upload); Vue.use(Button); Vue.use(Progress); ``` 这样,你就可以在Spring Boot使用Ant Design的组件来实现文件上传进度条了。当用户选择文件并点击上传按钮时,文件将被发送到Spring Boot后端,并通过回调函数更新上传进度条的状态。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值