java/extjs上传文件,显示真实进度条
当前idle状态!捣腾了一个文件上传功能,小温故了一把java/servlet上传的原理。
上传代码未用struts2,读取进度时才用了一下,本身struts2也把下面2个开源包'集成'进去了!代码都是在网上cp的,自己拼凑,加了一些注释。
当然,如果页面上没有Form表单(甚至是也未用struts2框架),就无法以表单(mutilpart/form-data格式)提交到后台,这时候可以借用第三方控件,如:flash插件或 (c++ ocx)控件等,辅助模仿form表单提交到jsp页面,再用jsp接收输入流,达到上传文件的目的!
如若想详细了解servlet上传,请参见这位大神的文章:http://www.ibm.com/developerworks/cn/java/fileup/
用struts2框架上传的文章:http://blog.csdn.net/lenotang/article/details/2784843
?
需要的jar:commons-fileupload-x.x.x.jar 和 commons-io-x.x.x.jar
?
首先是前端页面代码,(extjs3.3.1)
?
var m =0 ;var _interval; Ext.onReady(function() {var formPanel = new Ext.form.FormPanel({ labelWidth:80,id:'formPanel', bodyStyle:'padding:5 0 0 0 ', height:515, width:200, frame:true, fileUpload:true, items:[new Ext.form.TextField({ id:'excelUpload', anchor:'90%', height:30, width:350, name:'file', inputType:'file', fieldLabel:'文件选择' })] }); var upLoadFile = new Ext.Toolbar.Button({ text:'上传', listeners:{ 'click': uploadFiles }}); new Ext.Window({ title:'上传文件', width:400, height:140, minWidth:400, id:'uploadWin', minHeight:140, layout:'fit', plain:true, bodyStyle:'padding:5px;', buttonAlign:'center', items:formPanel, buttons:[upLoadFile] }).show(); });function uploadFiles(t){var excelName = Ext.getCmp('excelUpload').getRawValue();// 上传文件名称的路径 if (excelName == ""){ Ext.Msg.alert("提示","请选择需要上传的文件!"); return; }else { var array = new Array(); array = excelName.split("\"); var length = array.length; var fileName = ""; var index = 0; for (index = 0; index < length; index++) { if (fileName == "") { fileName = array[index]; } else { fileName = fileName + "/" + array[index]; } } _interval = setInterval("showRequest()", 100); Ext.getCmp("formPanel").getForm().submit({ url:'servlet/fileUpload', method:'POST', success:function(form, action, o) { Ext.MessageBox.alert("提示信息",action.result.message); Ext.getCmp("uploadWin").setTitle("上传文件"); }, failure : function(form, action) { Ext.MessageBox.alert("提示信息","请求失败,文件上传失败"); } }); } }function showRequest(){Ext.Ajax.request( { url : 'loginAction/getUploadPrcent.action', method : 'post', success: function(data, options){ Ext.getCmp("uploadWin").setTitle("上传文件:已经写入("+data.responseText+")"); if(data.responseText =='100%'){ clearInterval(_interval); Ext.getCmp("uploadWin").setTitle("上传文件:写入完成,请稍等..."); return; } m++ ; } }); }
? ?再贴监听方法:
?
??
public class UploadProgressListener implements ProgressListener {//要继承ProgressListenerprivate double megaBytes = -1; private HttpSession session; public UploadProgressListener(HttpServletRequest request) { session=request.getSession(); } public void update(long pBytesRead, long pContentLength, int pItems) { double mBytes = pBytesRead / 1000000; double total=pContentLength/1000000; if (megaBytes == mBytes) { return; } System.out.println("total====>"+total); System.out.println("mBytes====>"+mBytes); megaBytes = mBytes; System.out.println("megaBytes====>"+megaBytes); System.out.println("We are currently reading item " + pItems); if (pContentLength == -1) { System.out.println("So far, " + pBytesRead + " bytes have been read."); } else { System.out.println("So far, " + pBytesRead + " of " + pContentLength + " bytes have been read."); double read=(mBytes/total); NumberFormat nf=NumberFormat.getPercentInstance(); System.out.println("生成读取的百分比 并放入session中===>"+nf.format(read));//生成读取的百分比 并放入session中 session.setAttribute("readPrcnt", nf.format(read)); } } }
? ?再贴:上传dopost()方法:
??
public class fileUpload extends HttpServlet {private static final long serialVersionUID = 1L;public fileUpload() {super();}public void destroy() {super.destroy();}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setCharacterEncoding("UTF-8");//文件名中文乱码问题,可调用ServletUpLoader的setHeaderEncoding方法,或者设置request的setCharacterEncoding属性boolean isMultipart = ServletFileUpload.isMultipartContent(request); //判断上传表单是否为multipart/form-data类型if (isMultipart) { // 创建磁盘工厂,利用构造器实现内存数据储存量和临时储存路径 DiskFileItemFactory factory=new DiskFileItemFactory(); factory.setSizeThreshold(4096); // 设置文件临时存储路径 factory.setRepository(new File(System.getProperty("java.io.tmpdir"))); // 产生一新的文件上传处理程式 ServletFileUpload upload = new ServletFileUpload(factory); ProgressListener progressListener = new UploadProgressListener(request); request.getSession().setAttribute("progress", progressListener); upload.setProgressListener(progressListener); //文件名中文乱码问题,可调用ServletUpLoader的setHeaderEncoding方法,或者设置request的setCharacterEncoding属性 upload.setSizeMax(1024 * 1024 * 100); // 设置允许用户上传文件大小,单位:字节 FileOutputStream out = null ; InputStream in = null; // 得到所有的表单域,它们目前都被当作FileItem try { // 解析request对象,并把表单中的每一个输入项包装成一个fileItem 对象,并返回一个保存了所有FileItem的list集合。 //upload对象是使用DiskFileItemFactory 对象创建的ServletFileUpload对象,并设置了临时文件路径 传输文件大小等等。 List<FileItem> list = upload.parseRequest(request); Iterator it=list.iterator(); while(it.hasNext()) { FileItem item=(FileItem)it.next();// 每一个item就代表一个表单输出项 String filename = item.getName(); if(item.getName() != null && !item.isFormField()){ // 得到上传文件的名称,并截取 String savePath = this.getServletContext().getRealPath("/upload");//在WebRoot下面建了一个文件夹 String extensionName = filename.substring(filename.lastIndexOf(".") + 1);//获取文件后缀名 out=new FileOutputStream(savePath+"\"+ UUID.randomUUID()+"."+extensionName); in = item.getInputStream(); byte buffer[] = new byte[1024]; int len = 0; while((len=in.read(buffer))>0){ out.write(buffer,0,len); } in.close(); out.close(); response.setContentType("text/html;charset=GB2312"); response.getWriter().print("{'success':true,'message':'上传成功'}"); } item.delete(); } } catch (FileUploadException e) {e.printStackTrace();} finally{try{response.getWriter().close();in.close(); out.close();}catch(Exception ex){System.out.println(ex);}} }}public void init() throws ServletException {// Put your code here}}
? ? web.xml servlet配置:
?
??
<servlet> <servlet-name>fileUpload</servlet-name> <servlet-class>upload.fileUpload</servlet-class> </servlet> <servlet-mapping> <servlet-name>fileUpload</servlet-name> <url-pattern>/servlet/fileUpload</url-pattern> </servlet-mapping>
?
?
? ??