Struts2实现文件上传时显示进度条功能
最近在做一个资源共享的项目中,采用了Struts2.1.8+Spring2.5.6+hibernate3.32的框架整合方式进行开发。在文件上传这块,因为需要实现文件上传时显示进度条的功能,所以尝试了一下。怕以后忘记,先贴出来分享下。
要在上传文件时能显示进度条,首先需要实时的获知web服务端接收了多少字节,以及文件总大小,这里我们在页面上使用AJAX技术每一秒向服务器发送一次请求来获得需要的实时上传信息。但是当我们使用struts2后怎么在服务端获得实时的上传大小呢?这里需要用到commons-fileupload中的progressListener接口,实现这个接口,然后再实现一个自己的解析器,并在解析器中添加自己实现的那个progressListener;然后再替换struts2自带的解析器(struts2自带的解析器类没有添加progressListener),然后就可以了。下面看看主要的代码(技术有限,如有不对之处,望不吝点解):
监听器:
importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpSession; importorg.apache.commons.fileupload.ProgressListener; publicclassResourceProgressListenerimplementsProgressListener{ privateHttpSessionsession; publicResourceProgressListener(HttpServletRequestrequest){ session=request.getSession(); ResourceFileUploadStatusnewUploadStatus=newResourceFileUploadStatus(); session.setAttribute("currentUploadStatus",newUploadStatus); } publicvoidupdate(longreadedBytes,longtotalBytes,intcurrentItem){ ResourceFileUploadStatusstatus=(ResourceFileUploadStatus)session.getAttribute("currentUploadStatus"); status.setReadedBytes(readedBytes); status.setTotalBytes(totalBytes); status.setCurrentItem(currentItem); } }
上传状态类:
publicclassResourceFileUploadStatus{ privatelongreadedBytes=0L; privatelongtotalBytes=0L; privateintcurrentItem=0; publiclonggetReadedBytes(){ returnreadedBytes; } publicvoidsetReadedBytes(longbytes){ readedBytes=bytes; } publiclonggetTotalBytes(){ returntotalBytes; } publicvoidsetTotalBytes(longbytes){ totalBytes=bytes; } publicintgetCurrentItem(){ returncurrentItem; } publicvoidsetCurrentItem(intitem){ currentItem=item; } }
实现自己的解析器类:方法比较简单,找到struts2实现的解析器类,把代码拷贝过来然后添加上监听器即可。这个类代码较多就不整个文件拷了,主要是在parse方法里添加。Parse方法代码如下:红色标注部分即是需要自己添加的progressListener.
publicvoidparse(HttpServletRequestservletRequest,StringsaveDir) throwsIOException{ System.out.println("执行自定义MultiPartRequest"); DiskFileItemFactoryfac=newDiskFileItemFactory(); //Makesurethatthedataiswrittentofile fac.setSizeThreshold(0); if(saveDir!=null){ fac.setRepository(newFile(saveDir)); } //Parsetherequest try{ ServletFileUploadupload=newServletFileUpload(fac); upload.setSizeMax(maxSize); ResourceProgressListenerprogressListener=newResourceProgressListener(servletRequest);//新建一个监听器 upload.setProgressListener(progressListener);//添加自己的监听器 Listitems=upload.parseRequest(createRequestContext(servletRequest)); for(Objectitem1:items){ FileItemitem=(FileItem)item1; 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=servletRequest.getCharacterEncoding(); if(charset!=null){ values.add(item.getString(charset)); }else{ values.add(item.getString()); } params.put(item.getFieldName(),values); }else{ LOG.debug("Itemisafileupload"); //Skipfileuploadsthatdon'thaveafilename-meaningthatnofilewasselected. if(item.getName()==null||item.getName().trim().length()<1){ LOG.debug("Nofilehasbeenuploadedforthefield:"+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(FileUploadExceptione){ LOG.warn("Unabletoparserequest",e); errors.add(e.getMessage()); } }
上面的类建立完成后,还需要做一项工作:在struts.xml中添加如下内容:
下面就可以正常使用了,建立两个action,一个用来接收上传文件,以及对接收的文件作相应处理,处理完成后,在returnSUCCESS之前去除session中currentUploadStatus属性,一个用来为页面读取实时上传进度服务,这个类中只要将session中的currentUploadStatus对象拿出来按照相应格式返回给客户端即可。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。