项目中有个地方要实现用户上传头像的功能,这其实是个非常简单的功能,刚开始的时候,我的思路是采用使用Ext.Ajax来异步上传头像的,但是无论怎么实现后台都得不到文件,反复验证了后台的Struts2的代码没有错误,配置文件也没有错误,开始反思原因,经过google后发现,其实上传文件的时候用ajax是不能实现的,因为文件传递安全性方面的考虑,ajax只能将文件名传递到后台,并不能将文件本身传递给后台,要在extjs实现文件上传必须采用在form中提交的方式,不过为了实现类似于ajax的用户体验,可以在配置项中添加fileUpload:true的方式,来实现异步提交,而不必出现页面跳转的方式。废话不多说了看代码:
Extjs代码:
var imageform = new Ext.FormPanel({
id: 'imageform',
labelWidth: 80,
labelAlign : 'right',
border : false,
fileUpload: true,
bodyStyle : 'padding:10px 8px 8px 8px;',
items:[{
xtype: 'fieldset',
title: '设置头像',
collapsible: true,
labelWidth: 69,
collapsed: true,
layout:'form',
items: [{
xtype: 'fileuploadfield',
id: 'upload',
name: 'upload',
emptyText: '选择相片地址',
fieldLabel: '上传路径',
buttonText: '',
width:440,
buttonCfg: {
iconCls: 'upload-avatar'
},
anchor : '96%'
},{
border:false,
layout:'form',
fieldLabel : "预览图片",
items:[
{
xtype:'panel',
border:false,
layout:'column',
items:[{
xtype : 'box',
id : 'browseImage',
columnWidth:.35,
bodyStyle:'padding:10px 10px 10px 10px;',
autoEl : {
width : 102,
height : 125,
tag : 'img',
src : avatarurl
}
},{
columnWidth:.5,
labelAlign :'left',
border:false,
buttonAlign:'center',
bodyStyle:'margin-left:10px;padding:5px',
items:[{
xtype : 'label',
fieldLabel:'',
html: '<ul><li>1、图片格式只能是jpg格式。</li></ul><br/>'
},{
xtype : 'label',
fieldLabel:'',
html: '<ul><li>2、图片大小不超过300K。</li></ul><br/>'
},{
xtype : 'label',
fieldLabel:'',
html: '<ul><li>3、图片默认分辨率为102*125。</li></ul><br/>'
}] ,
buttons:[{
xtype : 'button',
fieldLabel:'',
text:'上传头像',
handler: function(){
var file_path = Ext.getCmp('upload').getValue();
var str = file_path.substr(file_path.lastIndexOf('.')+1,file_path.length);
if(str!='JPG'&&str!='jpg'){
Ext.Msg.alert('错误', "上传的图像只能是jpg格式!");
return false;
}
if(imageform.getForm().isValid()){
imageform.getForm().submit({
url: '/SchoolManageSystem/upLoadAvatar.do',
success:function(form, action){
var isSuc = action.result.success;
var message = action.result.message;
var image_url = "/SchoolManageSystem"+ action.result.avatarurl;
if(isSuc=='true'){
Ext.Msg.alert('消息', message);
}else{
Ext.Msg.alert('错误', message);
}
Ext.getCmp("browseImage").getEl().dom.src=image_url;
},
failure:function(form, action){
var isSuc = action.result.success;
var message = action.result.message;
if(isSuc=='true'){
Ext.Msg.alert('消息', message);
}else{
Ext.Msg.alert('错误', message);
}
Ext.getCmp("browseImage").getEl().dom.src=image_url;
}
});
}
}
}
]
}]
}]
}]
}]
})
struts2的配置文件:
<package name="default" extends="json-default">
<action name="upLoadAvatar" class="cn.action.UserinfoAction" method="upLoadAvatar">
<result name="success" type="json">
<param name="ContentType">text/html</param>
<param name="includeProperties">avatarurl,message,success</param>
</result>
</action>
</package>
Java代码如:
private File upload;
private String avatarurl;
private String uploadContentType;
private String uploadFileName;
。。。。
/**
* 上传用户头像
* @return
*/
public String upLoadAvatar() {
int BUFFER_SIZE = 16 * 1024;
InputStream in = null ;
OutputStream out = null ;
if(upload==null){
message = "文件不能为空";
avatarurl = "/images/login/photo-head.jpg";
success = false;
return SUCCESS;
}
long length = Math.round(upload.length()/1024);//文件大小,kb单位
if(length>600){
message = "文件大小超过300K的限制";
avatarurl = "/images/login/photo-head.jpg";
success = false;
return SUCCESS;
}
Map session = ActionContext.getContext().getSession();
int school_id = ( (UserInformation)session.get("ui")).getSchool_id();
int type = ( (UserInformation)session.get("ui")).getType();
String username = ( (UserInformation)session.get("ui")).getUsername();
int year = Calendar.getInstance().getTime().getYear()+1900;
String uploaddir = File.separator+"upload"+File.separator+school_id+File.separator+year+File.separator;
String relative = "/upload/"+school_id+"/"+year+"/";
Long timestamp = System.currentTimeMillis();
String imageName = username + "_" + timestamp+".jpg";
String realaddr = ServletActionContext.getServletContext().getRealPath(uploaddir);
File saveFile = new File(new File(realaddr), imageName);
if (!saveFile.getParentFile().exists()) {
saveFile.getParentFile().mkdirs();
}
try {
in = new BufferedInputStream( new FileInputStream(upload), BUFFER_SIZE );
out = new BufferedOutputStream( new FileOutputStream(saveFile), BUFFER_SIZE );
byte [] buffer = new byte [ BUFFER_SIZE ];
int len = 0;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
out.flush();
}
。。。。其他的业务代码省略
success = true;
message = "上传成功";
} catch (IOException e) {
e.printStackTrace();
}finally {
if ( null != in) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if ( null != out) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return SUCCESS;
}
这样前台就可以传递图片到后台了,其实传递其他的文件也是相同的道理。
图片效果: