原理:利用Ajax在客户端一直查询服务器端的上传进度,取得进度的状态文本信息(xml,json格式的文本等),然后利用JS解析,显示在前台。在Struts2.0中,框架事先已经定义一种监听器:ProgressListener(进度监听器),里面有一个update(longreadedBytes,longtotalBytes,intcurrentItem)方法,其中,readedBytes是已经上传到服务器的位数,而totalBytes是上传文件总位数.当文件已二进制的方式上传时,每上传一部分数据,就会调用这个方法一次。故要实现监听进度,必须实现这个接口,并实现update方法,在update方法中保存这个进度到session。当客服端需要进度的信息时,只需要访问某个action,在这个action中读取session中保存的进度状态就可以了.上传文件可大致分为两个阶段:1.上传到服务器上,在临时目录中2.从临时目录中把文件移到指定目录(由自己写的action处理),而struts2.的监听器只监听第一阶段。实现:(源代码下载:)第一步:实现ProgressListener接口,实现update()方法,详情见action包中的FileUploadListener.java文件,里面有一个自定义的类:State,它描述的是进度的状态,详情请看State注释。Update方法要做的就是不断地更新session中的state对象代码如下:viewplaincopytoclipboardprint?1.preclass=htmlname=codepackageaction;2.3.importjavax.servlet.http.HttpServletRequest;4.importjavax.servlet.http.HttpSession;5.6.importorg.apache.commons.fileupload.ProgressListener;7.8.publicclassFileUploadListenerimplementsProgressListener{9.privateHttpSessionsession;10.11.publicFileUploadListener(HttpServletRequestrequest){12.session=request.getSession();13.Statestate=newState();14.session.setAttribute(state,state);15.}16.@Override17.publicvoidupdate(longreadedBytes,longtotalBytes,intcurrentItem){18.//TODOAuto-generatedmethodstub19.System.out.println(update:+readedBytes+;+totalBytes+;+currentItem);20.21.Statestate=(State)session.getAttribute(state);22.23.state.setReadedBytes(readedBytes);24.state.setTotalBytes(totalBytes);25.state.setCurrentItem(currentItem);26.}27.}preclass=htmlname=codepimportjavax.servlet.http.HttpSimportjavax.servlet.http.HttpSimportorg.apache.commons.fileuState类:viewplaincopytoclipboardprint?1.packageaction;2.3.publicclassState{4.privatelongreadedBytes=0L;/*已经上传的位数*/5.privatelongtotalBytes=0L;/*文件所占位数*/6.privateintcurrentItem=0;7.privateintrate=0;/*上传百分比*/8.publiclonggetReadedBytes(){9.returnreadedBytes;10.}11.12.publicvoidsetReadedBytes(longreadedBytes){13.this.readedBytes=readedBytes;14.}15.16.publiclonggetTotalBytes(){17.returntotalBytes;18.}19.20.publicvoidsetTotalBytes(longtotalBytes){21.this.totalBytes=totalBytes;22.}23.publicintgetCurrentItem(){24.returncurrentItem;25.}26.27.publicvoidsetCurrentItem(intcurrentItem){28.this.currentItem=currentItem;29.}30.31.publicintgetRate(){32.returnrate;33.}34.publicvoidsetRate(intrate){35.this.rate=rate;36.}37.}packageaction;publicclassState{privatelongreadedByteprivatelongtotalBytes=0privateintcurrentItem=0第二步:将监听器注入到struts2.0的MultiPartRequest封装类中,客户端发送request到服务器,struts2.0会将request封装成MultiPartRequest。因此必须将监听器注入到MultiPartRequest中。只需要在MultiPartRequest中加入以下两句:FileUploadListenerprogressListener=newFileUploadListener(servletRequest);upload.setProgressListener(progressListener);//添加自己的监听器所以重新写一个新类MyMultiPartRequest代替MultiPartRequest,代码与org.apache.struts2.dispatcher.multipart.MultiPartRequest一样,在方法privateListFileItemparseRequest(HttpServletRequestservletRequest,StringsaveDir)中加入监听器.如下:viewplaincopytoclipboardprint?1.packageaction;2.3.importcom.opensymphony.xwork2.inject.Inject;4.importcom.opensymphony.xwork2.util.logging.Logger;5.importcom.opensymphony.xwork2.util.logging.LoggerFactory;6.importorg.apache.commons.fileupload.FileItem;7.importorg.apache.commons.fileupload.FileUploadException;8.importorg.apache.commons.fileupload.RequestContext;9.importorg.apache.commons.fileupload.disk.DiskFileItem;10.importorg.apache.commons.fileupload.disk.DiskFileItemFactory;11.importorg.apache.commons.fileupload.servlet.ServletFileUpload;12.importorg.apache.struts2.StrutsConstants;13.14.importjavax.servlet.http.HttpServletRequest;15.importjava.io.File;16.importjava.io.IOException;17.importjava.io.InputStream;18.importjava.io.UnsupportedEncodingException;19.importjava.util.ArrayList;20.importjava.util.Collections;21.importjava.util.Enumeration;22.importjava.util.HashMap;23.importjava.util.List;24.importjava.util.Map;25.26.27.importorg.apache.struts2.dispatcher.multipart.MultiPartRequest;28.29.publicclassMyMultiPartRequestimplementsMultiPartRequest{30.staticfinalLoggerLOG=LoggerFactory.getLogger(MultiPartRequest.class);31.32.//mapsparametername-ListofFileItemobjects33.protectedMapString,ListFileItemfiles=newHashMapString,ListFileItem();34.35.//mapsparametername-Listofparamvalues36.protectedMapString,ListStringparams=newHashMapString,ListString();37.38.//anyerrorswhileprocessingthisrequest39.protectedListStringerrors=newArrayListString();40.41.protectedlongmaxSize;42.43.@Inject(StrutsConstants.STRUTS_MULTIPART_MAXSIZE)44.publicvoidsetMaxSize(StringmaxSize){45.this.maxSize=Long.parseLong(maxSize);46.}47.48./**49.*Createsanewrequestwrappertohandlemulti-partdatausingmethodsadaptedfromJasonPell's50.*multipartclasses(seeclassdescription).51.*52.*@paramsaveDirthedirectorytosaveoffthefile53.*@paramrequesttherequestcontainingthemultipart54.*@throwsjava.io.IOExceptionisthrownifencodingfails.55.*/56.publicvoidparse(HttpServletRequestrequest,StringsaveDir)throwsIOException{57.try{58.processUpload(request,saveDir);59.}catch(FileUploadExceptione){60.LOG.warn(Unableto