一个典型的Extjs4上传文件表单:
Ext.define('org.allenz.UploadFormPanel', {
extend : 'Ext.form.Panel',
initComponent : function() {
var states = Ext.create('Ext.data.Store', {
fields : [ 'name', 'value' ],
data : [ {
name : '成功',
value : 0
}, {
name : '失败',
value : 1
}, {
name : '模拟服务器错误',
value : 2
} ]
});
var me = this;
Ext.apply(me, {
width : 300,
height : 100,
items : [ {
xtype : 'filefield',
fieldLabel : '上传文件',
name : 'upload',
buttonText : '浏览',
allowBlank : false
}, {
xtype : 'combo',
fieldLabel : '上传结果',
name : 'state',
allowBlank : false,
store : states,
displayField : 'name',
valueField : 'value'
} ],
dockedItems : [ {
xtype : 'toolbar',
dock : 'bottom',
ui : 'footer',
items : [ '->', {
text : '上传',
scope : me,
handler : me.onUpload
} ]
} ]
});
me.callParent(arguments);
},
onUpload : function() {
var me = this;
var form = me.getForm();
if (!form.isValid()) {
return;
}
// 浏览器提示
Ext.Msg.show({
msg : '正在上传...',
width : 300,
closable : false
});
form.submit({
url : 'upload.do',
scope : me,
success : me.uploadSuccess,
failure : me.uploadFailure
});
},
uploadSuccess : function(form, action) {
Ext.Msg.hide();
Ext.Msg.alert('提示', '上传成功!');
},
uploadFailure : function(form, action) {
Ext.Msg.hide();
var errorText;
switch (action.failureType) {
case Ext.form.action.Action.CLIENT_INVALID:
// 浏览器检查失败
errorText = '请选择上传文件!';
break;
case Ext.form.action.Action.SERVER_INVALID:
// 服务器检查文件失败
errorText = action.result.errors[0].message;
break;
default:
// 网络或服务器错误
errorText = '因网络或服务器错误,上传失败!';
}
Ext.Msg.alert('错误', errorText);
}
});
服务器端代码(基于Java Spring,只起返回作用不真正处理文件):
@Controller
public class UploadTestController {
@RequestMapping("/upload.do")
void upload(HttpServletResponse response, int state) throws IOException {
String result = null;
switch (state) {
case 0:
result = "{success:true}";
break;
case 1:
result = "{success:false,errors:[{message:'文件格式错误!'}]}";
break;
case 2:
throw new RuntimeException("抛出异常");
}
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
response.resetBuffer();
PrintWriter out = response.getWriter();
out.write(result);
out.close();
}
}
这里约定,服务器应返回的JSON字符串格式如下:
{success:boolean,errors:[{message:string}]}
在下拉框里选择“成功”或“失败”,上传文件后浏览器都能弹出对话框并显示信息,但是当选择'模拟服务器错误'后上传,浏览器并没有如我们预想那样提示“因网络或服务器错误,上传失败!”,而是在“正在上传...”提示中卡死,控制台提示“uncaught exception: You're trying to decode an invalid JSON String: ...”为什么会这样呢?
其实Ajax只能够收发基于文本的数据,是不能够处理二进制数据的。之所以看上去能够“异步上传”,是因为Extjs针对包含上传的表单使用了iframe提交的方法,流程如下:
1.在页面创建一个iframe和隐藏的form,form的各字段和Extjs表单字段相同;
2.将form的target指向该iframe,并监听iframe的onload事件;
3.提交这个form,待iframe的onload事件触发后(加载完成),读取iframe的innerHtml,并保存到responseText;
4.默认情况下,尝试将responseText进行JSON解码;
5.根据解码结果,调用success或failure回调。
隐患在第3步已经产生,因为不是使用Ajax提交,Extjs无法获取Http状态码,只能假定iframe返回的是JSON数据。而服务器出错时,返回的一般是Html错误页面,Extjs尝试对Html内容进行JSON解码最后抛出异常。
有没有办法处理这种情况呢?答案是有的。负责表单提交的Ext.form.Basic有一个参数errorReader,指定了errorReader时,解释responseText的责任就落到该数据读取器身上。在该数据读取器中先对responseText进行JSON解码测试,若发生异常,制造一个失败JSON对象。代码如下:
// 定义错误信息数据模型
Ext.define('org.allenz.ErrorModel', {
extend : 'Ext.data.Model',
fields : [ 'message' ]
});
// 定义上传错误数据读取器
Ext.define('org.allenz.UploadErrorReader', {
extend : 'Ext.data.reader.Json',
alternateClassName : 'Ext.data.UploadErrorReader',
alias : 'reader.upload',
// 设置错误信息根节点为errors
root : 'errors',
// 覆盖getResponseData
getResponseData : function(response) {
var data;
try {
// 尝试将responseText解码为JSON
data = Ext.decode(response.responseText);
} catch (ex) {
// 不能解码,则服务器没有正常返回,制造一个包含错误信息的JSON对象
// 最终这个data会被Reader转换为
// result = {success : false, errors : [yourErrorModel]}
// 从在回调函数中action.result读取
data = {
success : false,
total : 1,
errors : [ {
message : '因网络或服务器错误,上传失败!'
} ]
};
}
return data;
}
});
在Extjs表单类的initComponent函数末尾(执行this.callParent(arguments);后)加入:
var form = this.getForm();
var errorReader = Ext.create('org.allenz.UploadErrorReader', {
model : 'ErrorModel'
});
Ext.apply(form, {
errorReader : errorReader
});
注意返回数据格式要改为Reader能够辨认的格式,如{success:boolean,total:integer,errors:[yourErrorModel,...]}
- 大小: 3.9 KB
分享到:
相关推荐
Extjs4文件上传,后台struts2
用Ext编写的多文件上传组件,已封装。 支持多文件上传,文件下载,文件删除,
extjs 多文件上传extjs 多文件上传
ExtJS验证文件上传类型,详细讲述ExtJS如何验证文件上传文件的类型!
ExtJS原生多文件拖动上传组件 使用时修改包路径 1.多文件上传 2.支持拖动上传 3.支持图片压缩 4.支持图片合并 5.文件排序 可扩展实时图片预览 api //初始化画板 initCanvas //上传文件窗口 uploadWindow //初始化...
支持 自由添加和减少上传文件个数的Extjs多文件上传源代码,10分绝对值得,要注意的一点就是jsp里面引用的Ext的js和css要是2.2版本的
对应的描述看本人博文《ExtJS4 上传文件类型和大小的判断方法(实例) 》:http://blog.csdn.net/biboheart/article/details/10579175 在这里不具体描述了。看题也大概可以知道这些代码实现了什么应用。
EXTJS MultiFileUploadField 多文件 上传
extjs4.0版本 支持多文件文件上传,快键轻松!
Extjs4 swfupload 多文件 上传
本示例解决了strut2+swfupload+extjs4文件上传过程中,后台struts接收不到上传文件的问题。而这个问题如果用servlet做后台可能就不存在。开发者可以用本例源码移植到自己项目中使用 。
ExtJS4多文件上传,可单独对每个文件进行管理,有进度条。
官方或网上ExtJS实现多文件上传的UploadDialog只适用于ExtJS2.x,我经过修改使其使用于ExtJS3.x,并在修改时尽量尊重于原始功能代码,请大家放心使用!
Extjs 文件上传 strut2
Extjs多文件上传(非SWFUpload版)
功能强大的Struts2.0+Extjs实现的文件上传,包含文件上传进度,文件的下载,压缩,解压多文件删除等
extjs是一个多文件上传的控件。可以实现多文件上传。
批量上传文件,完整的列子,部署既可以使用,
NULL 博文链接:https://279469669.iteye.com/blog/1185024