文件上传其实是一个很基本的页面操作,以前也做过。在jsp+servlet时,关键点是只要指定jsp用于提交上传文件资源的form的enctype属性为multipart/form- data即可。这个属性 其实是设置了提交的内容是以数据流的方式提交给servlet的。当然也包含了文件的流,这样在servlet里利用common- fileupload.jar里的接口方法,解析这个流,就可以获得上传的文件的信息。 今天在利用ext的js代替了jsp时,却碰到了点小麻烦。现在总结如下。 其实利用ext实现的原理是一样的,只是编写js的过程中要主要,当发送ajax请求时,要保证所发的请求是在enctype为multipart/form-data的form中,否则,后台无法解析上传文件信息。 对于表单的定义可以采用如下方法: var uploadForm = new Ext.form.FormPanel({ url: "AuthManager.do?action=addCertificate",//ajax请求的地址 rame:true,//要设为true fileUpload:true,//一定要这一项,表明这个表单是做文件上传所用 id:'uploadForm', height:130, labelAlign: 'right', bodyStyle:'padding:6px 5px 0', //enctype : 'multipart/form-data', //其实这一项是没有用的,fileUpload:true的令一层意思也就是这个 items: new Ext.form.TextField({ xtype: 'textfield', //style:'margin-top:15px ', id:'upload_filepath', name:'file', allowBlank:false, fieldLabel:'选择文件', inputType:'file' //文件的形式 }) }) 在需要完成提价功能的时候,可以这么调用uploadForm.getForm().submit(); 这里需要指出的是,有一种做法会导致上传失败的:form依旧是如上的写法,只是里面没有url这一个属性,form是在发送ajax请求时调用的: var uploadWin = new Ext.Window({ title:'<span style="/" mce_style="/""font-size:12px/">上传文件</span>', width:400, height:130, items:[uploadForm],//引入了上传文件的表单 buttonAlign :'center', buttons:[{ text:'<span style="/" mce_style="/""font-size:12px/">上传</span>', handler:uploadFile//调用函数完成提交动作 }] }); //导入证书函数function uploadFile(){ Ext.Ajax.request({ url: "AuthManager.do?action=addCertificate", ....}) }
这样发出的请求跟第一种是一模一样的,但是却会导致上传的失败。从抛出的异常:“request must at least contains multipart/form-data or multipart/... stream, but ......”说明请求的表单是一个普通默认enctype的表单。这是怎么回事呢? 原来上传的表单虽然是正确的,但是请求却不是在正确的表单里进行的,所以导致了错误。 有了页面上的资源,后台实现其实与JSP+SERVLET是一样的,代码如下: public String[] uploadFileTemp(HttpServletRequest request) throws X { String[] filePaths = null; try{ RequestContext ctx = new ServletRequestContext(request); boolean isMultiPart = FileUpload.isMultipartContent(ctx);//必须是multi的表单模式才行 System.out.println("content type: " + ctx.getContentType()); if(isMultiPart){ DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setSizeThreshold(1000 * 1024); // 设置保存到内存中的大小:1M ServletFileUpload upload = new ServletFileUpload(factory); upload.setSizeMax(500 * 1024 * 1024);// 设置最大上传文件的大小500M List items = upload.parseRequest(ctx);//解析请求里的上传文件单元 if(items != null && items.size() > 0){ filePaths = new String[items.size()];//初始化返回的文件名数组 Iterator it = items.iterator(); int flag = -1; while (it.hasNext()) { flag ++; FileItem item = (FileItem) it.next(); boolean isForm = item.isFormField();//是否是表单域 if (!isForm) { //如果不适表单域,则是文件上传 String fileName = item.getName();//获取上传的文件名 if (!fileName.equals("")) { //到达这个时候,上传文件所必须的条件都满足了,可以上传了,首先要给上传的文件起个名字 String writeFile = "" + System.currentTimeMillis();//以时间起个名字。 filePaths[flag] = writeFile; System.out.println(flag + ": " + filePaths[flag]); writeFile = Constant.uploadPath + writeFile;//文件的全路径 File file = new File(writeFile); item.write(file);//上传文件 } } } } } }catch(Exception e){ log.error("上传文件失败:" + e.getMessage()); throw new X().set(e); } return filePaths; }