文件上传其实是一个很基本的页面操作,以前也做过。
在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,//一定要这一项,表明这个表单是做文件上传所用
//enctype : 'multipart/form-data', //其实这一项是没有用的,fileUpload:true的令一层意思也就是这个
id:'uploadForm',
height:130,
labelAlign: 'right',
bodyStyle:'padding:6px 5px 0',
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",
method:'post',
extraParams:{json:'json'}
});
这样发出的请求跟第一种是一模一样的,但是却会导致上传的失败。 从抛出的异常:“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; } }