第一次再iteye上发表博客文章,有不足之处高手指正。
前不久在项目中用ExtJS用过上传组件,本来开始是打算用FormPanel实现上传,但是我们开发的网站后台管理平台,每天上传的东西很多,所有我就考虑用UploadDialog实现上传。
UploadDialog这个控件看上去是多文件上传,但是实际上还是单个文件实现上传的。
具体实现步骤如下所示:
1. 引入控件的文件
<link rel="stylesheet" type="text/css" href="./upload/extjs/UploadDialog/css/Ext.ux.UploadDialog.css">
<script type="text/javascript" src="./upload/extjs/UploadDialog/UploadDialog.js"></script>
这两个文件需要单独去下载UploadDialog控件的这个包,这里不贴上了。
2. 页面实现,我这里是将JS全部嵌入到JSP中,其作用写在代码的注释
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>文件上传</title> <link rel="stylesheet" type="text/css" href="./upload/extjs/resources/css/ext-all.css"> <link rel="stylesheet" type="text/css" href="./upload/extjs/UploadDialog/css/Ext.ux.UploadDialog.css"> <script type="text/javascript" src="./upload/extjs/ext-base.js"></script> <script type="text/javascript" src="./upload/extjs/ext-all.js"></script> <script type="text/javascript" src="./upload/extjs/ext-lang-zh_CN.js"></script> <script type="text/javascript" src="./upload/extjs/UploadDialog/UploadDialog.js"></script> </head> <body> <script type="text/javascript"> Ext.onReady(function() { dialog = new Ext.ux.UploadDialog.Dialog({ title: '文件上传' , url:'./json/upload_filesUpload.action' , //这里我用struts2做后台处理 post_var_name:'files',//这里是自己定义的,默认的名字叫file width : 450, height : 300, minWidth : 450, minHeight : 300, draggable : true , resizable : true , //autoCreate: true, constraintoviewport: true , //permitted_extensions:[ 'JPG' , 'jpg' , 'jpeg' , 'JPEG' , 'GIF' , 'gif' , 'png' , 'PNG' ], modal: true , reset_on_hide: false , allow_close_on_upload: false , //关闭上传窗口是否仍然上传文件 //upload_autostart: true //是否自动上传文件 upload_autostart: false }); dialog.show(); dialog.on( 'uploadsuccess' , onUploadSuccess); //定义上传成功回调函数 dialog.on( 'uploadfailed' , onUploadFailed); //定义上传失败回调函数 dialog.on( 'uploaderror' , onUploadFailed); //定义上传出错回调函数 dialog.on( 'uploadcomplete' , onUploadComplete); //定义上传完成回调函数 }) //文件上传成功后的回调函数 onUploadSuccess = function(dialog, filename, resp_data, record){ if(!resp_data.success){ alert(resp_data.message);//resp_data是json格式的数据 } } //文件上传失败后的回调函数 onUploadFailed = function(dialog, filename, resp_data, record){ alert(resp_data.message); } //文件上传完成后的回调函数 onUploadComplete = function(dialog){ dialog.hide(); } </script> </body> </html>
3. 后台上传action,这个代码和普通的上传差不多,基本都是读文件的操作
package ext.util.upload; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; /** * Struts单文件上传类 * 支持使用UploadDialog控件上传文件 * @author lizhenbin * */ public class SingleUploadAction extends ActionSupport { private static final int BUFFER_SIZE = 4 * 1024; //设置文件上传的缓冲区的大小 private String jsonString; //返回Json给控件 private File files; //上传的文件(用UploadDialog时名字固定写死,如下一致) private String filesFileName; //上传文件名 private String filesContentType; //上传文件类型 private String savePath; //保存文件的目标路径(依赖注入)uploadFileName; public String getJsonString() { return jsonString; } public void setJsonString(String jsonString) { this.jsonString = jsonString; } public File getFiles() { return files; } public void setFiles(File files) { this.files = files; } public String getFilesFileName() { return filesFileName; } public void setFilesFileName(String filesFileName) { this.filesFileName = filesFileName; } public String getFilesContentType() { return filesContentType; } public void setFilesContentType(String filesContentType) { this.filesContentType = filesContentType; } public String getSavePath() { return savePath; } public void setSavePath(String savePath) { this.savePath = savePath; } //自己封装的一个把源文件对象复制成目标文件对象 private static boolean copy(File src, File dst) { InputStream in = null; OutputStream out = null; boolean flag = true; try { in = new BufferedInputStream(new FileInputStream(src), BUFFER_SIZE); out = new BufferedOutputStream(new FileOutputStream(dst),BUFFER_SIZE); System.out.println("============>上传文件的大小:"+in.available()/1024+"K"); //计算出上传文件的大小 System.out.println("============>上传文件的大小:"+in.available()/(1024*1024)+"M"); byte[] buffer = new byte[BUFFER_SIZE]; int len = 0; while ((len = in.read(buffer)) > 0) { out.write(buffer, 0, len); } } catch (Exception e) { e.printStackTrace(); flag = false; } finally { if (null != in) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != out) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } return flag; } //多文件的上传 public String filesUpload() { // 根据服务器的文件保存地址和原文件名创建目录文件全路径 String dstPath = ServletActionContext.getServletContext().getRealPath(this.getSavePath()) + "\\" + this.filesFileName; //创建文件目录 File myCreatePath = new File(dstPath); if(!myCreatePath.isDirectory()) { myCreatePath.getParentFile().mkdirs(); } System.out.println("============>上传的文件的类型:"+ this.filesFileName); System.out.println("============>上传文件的名字:"+this.filesContentType); //File dstFile = new File(dstPath); //返回Json给回调函数 if(this.copy(files, myCreatePath)){ this.setJsonString("{'success':true,'message':'上传成功'}"); }else{ this.setJsonString("{'success':false,'message':'上传失败'}"); }; return "success"; } }
4. strut.xml的配置信息如下:
<!-- struts上传的最大值限制,可自己配置 --> <constant name="struts.multipart.maxSize" value="1024000000000"/>
<package name="weibo_json" namespace="/json" extends="json-default"> <!-- 多文件上传配置,注:menu_jsonvalue.jsp是用来返回json数据的 --> <action name="upload_*" method="{1}" class="ext.util.upload.SingleUploadAction"> <param name="savePath">/ext_upload</param> <result name="success">/jsonvalue.jsp</result> </action> </package>
5. 由于控件要得到json的返回数据,判断状态,我这里用到了一个jsonvalue.jsp的页面接收json数据
<%@ page language="java" pageEncoding="utf-8"%> <%@taglib prefix="s" uri="/struts-tags" %> <s:property value="jsonString" escape="false"/>
通过上面的五个步骤基本上就可以实现上传了,不过自己还得尝试一下,每个人的工程项目配置不一样,相信经过一番折腾也会收获良多。