struts2实现文件上传显示进度条效果
一.struts2读取进度原理分析(作为草稿存了好久,刚刚发布出来......)
1.在strut2中控制文件上传信息的类是实现MultiPartRequest接口的JakartaMultiPartRequest
其实第一次看到源文件时我打了个退堂鼓,因为觉得内容太长了,不想看。冷静下来将思路理顺,将分开的各个方法还原到一个方方中中,发现还是很好理解的:
@Override publicvoidparse(HttpServletRequestrequest,StringsaveDir) throwsIOException{ setLocale(request); //规定了File文件的格式(如文件名必须是xxFileName,文件类型xxContentType),并定义了File的保存路径DiskFileItemFactoryfactory=newDiskFileItemFactory(); ServletFileUploadupload=newServletFileUpload(factory);//处理文件上传的servlet upload.setProgressListener(newFileUploadProgressListener(request));//为文件上传添加监听factory.setSizeThreshold(0);//if(saveDir!=null factory.setRepository(newFile(saveDir));//临时路径 } try{ upload.setSizeMax(maxSize); Listitems=upload.parseRequest(createRequestContext(request));//获取所有请求 for(ObjectobItem:items){ FileItemitem=(FileItem)obItem;//获取每个请求的文件 if(LOG.isDebugEnabled()){ LOG.debug("Founditem"+item.getFieldName()); } if(item.isFormField()){//普通表单提交 LOG.debug("Itemisanormalformfield"); Listvalues; if(params.get(item.getFieldName())!=null){ values=params.get(item.getFieldName()); }else{ values=newArrayList (); } Stringcharset=request.getCharacterEncoding(); if(charset!=null){ values.add(item.getString(charset)); }else{ values.add(item.getString()); } params.put(item.getFieldName(),values); }else{//文件上传请求 LOG.debug("Itemisafileupload"); if(item.getName()==null ||item.getName().trim().length()<=0){ LOG.debug("Nofilehasbeenuplodedforthefiled:" +item.getFieldName()); continue; } List values; if(files.get(item.getFieldName())!=null){ values=files.get(item.getFieldName()); }else{ values=newArrayList (); } values.add(item); files.put(item.getFieldName(),values); } } }catch(FileUploadBase.SizeLimitExceededExceptione){ System.out.println("错误1:"+e); if(LOG.isWarnEnabled()){ LOG.warn("Requestexceededsizelimit!",e); } StringerrorMessage=buildErrorMessage(e,newObject[]{e.getPermittedSize(),e.getActualSize()}); if(!errors.contains(errorMessage)){ errors.add(errorMessage); } }catch(Exceptione){ System.out.println("错误1:"+e); if(LOG.isWarnEnabled()){ LOG.warn("Unabletoparserequest",e); } StringerrorMessage=buildErrorMessage(e,newObject[]{}); if(!errors.contains(errorMessage)){ errors.add(errorMessage); } } }
2. 文件上传监听文件FileUploadProgressListener.java
publicclassFileUploadProgressListenerimplementsProgressListener{ privatefinalHttpSessionsession; privatefinalDecimalFormatformat=newDecimalFormat("#00.0"); publicFileUploadProgressListener(HttpServletRequestrequest){ session=request.getSession(); FileUploadStatusstatus=newFileUploadStatus(); session.setAttribute("uploadStatus",status); } @Override publicvoidupdate(longpBytesRead,longpContentLength,intpItems){ FileUploadStatusuploadStatus=(FileUploadStatus)session.getAttribute("uploadStatus"); DoubleuploadRate=(double)(pBytesRead*100/pContentLength); uploadStatus.setUploadRate(Double.valueOf(format.format(uploadRate))); uploadStatus.setReadedBytes(pBytesRead/1024); uploadStatus.setTotalBytes(pContentLength/1024); uploadStatus.setCurrentItems(pItems); } }
3.添加状态文件:FileUploadStatus.java
publicclassFileUploadStatus{ privateDoubleuploadRate=0.0; privateLongreadedBytes=0L; privateLongtotalBytes=0L; privateintcurrentItems=0; privateLonguploadSpeed=0L; privateLongstartTime=System.currentTimeMillis(); privateLongreadedTimes=0L; privateLongtotalTimes=0L; //"-1"错误"0"正常"1"完成 privateStringerror="0"; ... settergetter方法 ... }
4.Action类(如果是多文件上传,则将File FileName ContentType定义成数组形式即可)
/** *利用io流上传文件 */ publicclassFileStreamUploadActionextendsActionSupport{ /** *serialVersionUID作用:---相当于类的身份证。序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。 *有两种生成方式:一个是默认的1L,比如:privatestaticfinallongserialVersionUID=1L; *一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:privatestaticfinallong *serialVersionUID=xxxxL; */ privatestaticfinallongserialVersionUID=1L; privateFileimage; privateStringimageFileName; privateStringimageContentType; privateStringmessage; publicStringuploadFile(){ FileInputStreamin=null; FileOutputStreamout=null; System.out.println("文件名:"+imageFileName); try{ this.setNewFileName(imageFileName); StringrealPath=ServletActionContext.getServletContext() .getRealPath("/file"); FilefilePath=newFile(realPath); if(!filePath.exists()){//如果保存的路径不存在则创建 filePath.mkdir(); } if(image==null){ message="上传文件为空"; System.out.println(message); }else{ FilesaveFile=newFile(filePath,this.getNewFileName()); out=newFileOutputStream(saveFile); } in=newFileInputStream(image); byte[]byt=newbyte[1024]; intlength=0; while((length=in.read(byt))>0){ out.write(byt,0,length); out.flush(); } message="上传成功"; System.out.println(message); }catch(FileNotFoundExceptione){ message="找不到文件!"; e.printStackTrace(); }catch(IOExceptione){ message="文件读取失败!"; e.printStackTrace(); }finally{ closeStream(in,out); } return"uploadSucc"; } publicvoidcloseStream(FileInputStreamin,FileOutputStreamout){ try{ if(in!=null){ in.close(); } if(out!=null){ out.close(); } }catch(IOExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } } ... setter()getter() ... }
获取进度的Action
publicclassFileProgressActionextendsActionSupport{ privatestaticfinallongserialVersionUID=1L; privateFileUploadStatusuploadStatus; publicStringuploadPercent(){ HttpSessionsession=ServletActionContext.getRequest().getSession(); this.uploadStatus=(FileUploadStatus)session.getAttribute("uploadStatus"); if(uploadStatus==null){ System.out.println("actionisnull"); uploadStatus=newFileUploadStatus(); uploadStatus.setCurrentItems(0); } return"getPercent"; } publicFileUploadStatusgetUploadStatus(){ returnuploadStatus; } publicvoidsetUploadStatus(FileUploadStatusuploadStatus){ this.uploadStatus=uploadStatus; } }
5.struts.xml中
newFileName text/html uploadStatus
二. 进度条显示
View页面设置,利用ajaxfileupload.js来获取文件并进行异步上传,bootstrap中的进度条效果显示进度(利用setInterval间断的获取进度信息来形式一种进度的前进显示)
Inserttitlehere /bootstrap/js/bootstrap.js"> /bootstrap/js/jquery.showLoading.min.js"> varsetinterval; $(document).ready(function(){ $("#upload").click(function(){ $("#upload").addClass("disabled"); $("#upload").attr("disabled",true); $("#upload").attr("title","文件上传中..."); uploadFile(); setinterval=setInterval(uploadProgress,200); }); }); //文件上传 functionuploadFile(){ $.ajaxFileUpload({ url:'ajaxUploadFile_uploadFile.action', secureuri:false,//是否采用安全协议,默认为false fileElementId:'image', dataType:'json', success:function(data){ $("#showImage").attr("src","/FileUpLoadTest/file/"+data); } }); } //上传进度 functionuploadProgress(){ $.get("uploadPercent_uploadPercent.action","",function(data){ $("#ProgressRate").html("上传速度:"+data.uploadRate+"%"); $("#readBytes").html("以读取:"+data.readedBytes+"KB"); $("#totalBytes").html("总大小:"+data.totalBytes+"KB"); $("#progress").attr("style","width:"+data.uploadRate+"%;"); $("#progress").html(data.uploadRate+"%"); if(data.uploadRate==100){ clearInterval(setinterval); $("#progress").html("上传成功"); $("#upload").removeClass("disabled"); $("#upload").attr("disabled",false); } }); } 文件异步上传+进度条