需求来源是这样的:上传一个很大的excel文件到server, server会解析这个excel, 然后一条一条的插入到数据库,整个过程要耗费很长时间,因此当用户点击上传之后,需要显示一个进度条,并且能够根据后台的接收的数据量和处理的进度及时更新进度条。
分析:后台需要两个组件,uploadController.jsp用来接收并且处理数据,它会动态的把进度信息放到session,另一个组件processController.jsp用来更新进度条;当用户点“上传”之后,form被提交给uploadController.jsp,同时用js启动一个ajax请求到processController.jsp,ajax用获得的进度百分比更新进度条的显示进度,而且这个过程每秒重复一次;这就是本例的基本工作原理。
现在的问题是server接收数据的时候怎么知道接收的数据占总数据的多少? 如果我们从头自己写一个文件上传组件,那这个问题很好解决,关键是很多时候我们都是用的成熟的组件,比如apache commons fileupload; 比较幸运的是,apache早就想到了这个问题,所以预留了接口可以用来获取接收数据的百分比;因此我就用apache commons fileupload来接收上传文件。
uploadController.jsp:
<%@ page language="java" import="java.util.*, java.io.*, org.apache.commons.fileupload.*, org.apache.commons.fileupload.disk.DiskFileItemFactory, org.apache.commons.fileupload.servlet.ServletFileUpload" pageEncoding="utf-8"%> <% //注意上面的import的jar包是必须的 //下面是使用apache commons fileupload接收上传文件; FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); //因为内部类无法引用request,所以要实现一个。 class MyProgressListener implements ProgressListener{ private HttpServletRequest request = null; MyProgressListener(HttpServletRequest request){ this.request = request; } public void update(long pBytesRead, long pContentLength, int pItems) { double percentage = ((double)pBytesRead/(double)pContentLength); //上传的进度保存到session,以便processController.jsp使用 request.getSession().setAttribute("uploadPercentage", percentage); } } upload.setProgressListener(new MyProgressListener(request)); List items = upload.parseRequest(request); Iterator iter = items.iterator(); while (iter.hasNext()) { FileItem item = (FileItem) iter.next(); if (item.isFormField()){ } else { //String fieldName = item.getFieldName(); String fileName = item.getName(); //String contentType = item.getContentType(); System.out.println(); boolean isInMemory = item.isInMemory(); long sizeInBytes = item.getSize(); File uploadedFile = new File("c://" + System.currentTimeMillis() + fileName.substring(fileName.lastIndexOf("."))); item.write(uploadedFile); } } out.write("{success:true,msg:'保存上传文件数据并分析Excel成功!'}"); out.flush(); %>
processController.jsp:
<%@ page language="java" import="java.util.*" contentType = "text/html;charset=UTF-8" pageEncoding="utf-8"%> <% //注意上面的抬头是必须的。否则会有ajax乱码问题。 //从session取出uploadPercentage并送回浏览器 Object percent = request.getSession().getAttribute("uploadPercentage"); String msg = ""; double d = 0; if(percent==null){ d = 0; } else{ d = (Double)percent; //System.out.println("+++++++processController: " + d); } if(d<1){ //d<1代表正在上传, msg = "正在上传文件..."; out.write("{success:true, msg: '"+msg+"', percentage:'" + d + "', finished: false}"); } else if(d>=1){ //d>1 代表上传已经结束,开始处理分析excel, //本例只是模拟处理excel,在session中放置一个processExcelPercentage,代表分析excel的进度。 msg = "正在分析处理Excel..."; String finished = "false"; double processExcelPercentage = 0.0; Object o = request.getSession().getAttribute("processExcelPercentage"); if(o==null){ processExcelPercentage = 0.0; request.getSession().setAttribute("processExcelPercentage", 0.0); } else{ //模拟处理excel,百分比每次递增0.1 processExcelPercentage = (Double)o + 0.1; request.getSession().setAttribute("processExcelPercentage", processExcelPercentage); if(processExcelPercentage>=1){ //当processExcelPercentage>1代表excel分析完毕。 request.getSession().removeAttribute("uploadPercentage"); request.getSession().removeAttribute("processExcelPercentage"); //客户端判断是否结束的标志 finished = "true"; } } out.write("{success:true, msg: '"+msg+"', percentage:'" + processExcelPercentage + "', finished: "+ finished +"}"); //注意返回的数据,success代表状态 //percentage是百分比 //finished代表整个过程是否结束。 } out.flush(); %>
表单页面upload.html:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>File Upload Field Example</title> <link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css" /> <script type="text/javascript" src="/UploadFiles/2021-04-02/ext-base.js">
把这三个文件放到tomcat/webapps/ROOT/, 同时把ext的主要文件也放到这里,启动tomcat即可测试:http://localhost:8080/upload.html我的资源里面有完整的示例文件:点击下载, 下载zip文件之后解压到tomcat/webapps/ROOT/即可测试。
最后需要特别提醒,因为用到了apache 的fileUpload组件,因此,需要把common-fileupload.jar放到ROOT/WEB-INF/lib下。
Extjs,文件上传
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
更新日志
- 群星.2022-一不小心喵上你原声大碟【TME影音】【FLAC分轨】
- 《战锤40K星际战士2》卡在正在加入服务器解决方法
- 《勇者斗恶龙怪物仙境3》玩法内容介绍
- 《幸福工厂》无限报错解决方法
- 交错战线原始交易所推荐角色一览
- 战锤40K星际战士2战术职业介绍|战术职业技能效果一览
- 战锤40K星际战士2突击职业介绍|突击职业技能效果一览
- [妙音金曲]群星《悲情咖啡屋》(黑胶)2CD[DTS-WAV]
- 阿兰·达瓦卓玛《A-Lan阿兰唯美歌姬》2CD[DTS-WAV]
- 【小提琴】陈立新《思乡曲》2004[FLAC+CUE]
- 《战地》新作明年初大规模测试!EA已内部测试一年
- 《GTAOL》PC版时隔多年更新反作弊!小助手宣布跑路
- EA称AI是其业务核心!能提高开发效率、节约成本
- 卫华.1990-太阳升【BMG】【WAV+CUE】
- 呼吸乐队.1992-THEBREATHING【深飞】【WAV+CUE】