SWFUpload1
SWF多文件无刷新上传,利用flash完成多文件上传操作。服务器端可以用Struts、Servlet、JSP完成,这里用Struts1.x完成上传
1、 首先看下目录结构
SWFUpload这个文件夹是核心文件,里面的文件一个都不能少。
css文件夹是样式文件,所有的样式可以在此文件中修改完成
images是图片
jslib是js库文件,需要的上传的js文件和flash文件
其中handlers.js是上传中一系列的事件,可以在此文件中修改自己的上传所需要的事件。如开始上传、取消、停止上传等
swfupload.queue.js这个文件主要是完成将客户端选择的多一个文件一个个的排成一个队列,然后依次向服务器上传。
swfupload.swf是flash文件,就那个添加或上传的按钮
sample.html是完成后的上传实例
2、 首先看看客户端的sample.html中的js和html
内容
财务内部控制制度的内容财务内部控制制度的内容人员招聘与配置的内容项目成本控制的内容消防安全演练内容
SWFUpload 多文件上传示例
A.先介绍导入的js文件
这些文件是必须的,且在导入的时候注意你的路径和顺序。还有就文件编码,文件保存的不同编码可以会影响文件显示的乱码问题,charset就是文件保存的编码。
B.然后在其中是script脚本的参数详细讲解
设置flash文件
flash_url : "jslib/swfupload.swf",
设置服务器的上传地址
upload_url: "../upload.do",
提交到服务器的参数信息,这样就添加了一个param参数,值是uploadParams在服务器端用request.getParameter(“param”)就可以拿到值
post_params: {"param" : "uploadParams"},
上传文件的最大空间
file_size_limit : "200MB",
允许上传文件的类型,*.*是所有,*.txt只能上传文本
file_types : "*.*",
这个就服务器端要获得的文件的属性,相当于file的name
file_post_name: "uploadFile",
所有文件夹
file_types_description : "All Files",
上传文件选取的最大队列数
file_upload_limit : 50,
file_queue_limit : 0,
下面是上传按钮的设置
button_image_url: "images/TestImageNoText_65x29.png",
button_width: "65",
button_height: "29",
button_placeholder_id: "spanButtonPlaceHolder",
button_text: '
浏 览',
button_text_style: ".theFont { font-size: 12; }",
button_text_left_padding: 12,
button_text_top_padding: 3,
下面是上传事件和函数:
选择完文件后就触发
file_queued_handler : fileQueued,
上传文件错误时触发
file_queue_error_handler : fileQueueError,
上传文件弹出窗口,窗口关闭触发
file_dialog_complete_handler : fileDialogComplete,
开始上传触发
upload_start_handler : uploadStart,
upload_progress_handler : uploadProgress,
上传错误触发
upload_error_handler : uploadError,
上传成功
upload_success_handler : uploadSuccess,
完成
upload_complete_handler : uploadComplete,
队列中上传完成
queue_complete_handler : queueComplete
下面看看html代码:
值得介绍的是
这个span就会被flsah的浏览多代替,注意这里的id和上面js button_placeholder_id是对应的
这个是上传按钮,点击上传就会执行upload这个js方法
这个是停止上传的,可以取消当前正在上传的文件,运行stop方法
取消所有的队列文件
3、 官方的handlers被修改的几个方法
选择文件后显示文件的大小
function fileQueued(file) {
try {
var progress = new FileProgress(file, this.customSettings.progressTarget);
var size = file.size;
var unit = "B";
if (size > (1024 * 1024 * 1024)) {
unit = "GB";
size /= (1024 * 1024 * 1024);
} else if (size > (1024 * 1021)) {
unit = "MB";
size /= (1024 * 1024);
} else if (size > 1024) {
unit = "KB";
size /= 1024;
}
progress.setStatus("
" + size.toFixed(2) + " " + unit + " 等待上传......");
progress.toggleCancel(true, this);
} catch (ex) {
this.debug(ex);
}
}
显示当前文件上传进度的百分比
function uploadProgress(file, bytesLoaded, bytesTotal) {
try {
var percent = Math.ceil((bytesLoaded / bytesTotal) * 100);
var progress = new FileProgress(file, this.customSettings.progressTarget);
progress.setProgress(percent);
progress.setStatus("已上传 " + percent+ "% ......");
} catch (ex) {
this.debug(ex);
}
}
获取服务器端上传后返回的信息
function uploadSuccess(file, serverData) {
try {
var progress = new FileProgress(file, this.customSettings.progressTarget);
progress.setComplete();
var data = eval("(" + serverData + ")");
if (data.success == 0 || data.success == "0") {
progress.setStatus("上传完成!");
} else {
progress.setError();
progress.setStatus("上传失败!" + data.message);
}
progress.toggleCancel(false);
} catch (ex) {
this.debug(ex);
}
}
4、 下面看看服务器端的上传代码
//上传文件保存路径
public static String path = "/upload/";
//定义可以上传文件的后缀数组,默认"*",代表所有
public static String[] filePostfixs = { "*" };
public static String[] typeImages = { "gif", "jpeg", "png", "jpg", "tif", "bmp" };
public static String[] typeOthers = { "html", "htm", "doc", "xls", "txt", "zip", "rar", "pdf", "cll" };
//上传文件的最大长度
public static long maxFileSize = 1024 * 1024 * 2;//2M
//一次读取多少字节
public static int bufferSize = 1024 * 8;
private final static void init() {
if (bufferSize > Integer.MAX_VALUE) {
bufferSize = 1024 * 8;
} else if (bufferSize < 8) {
bufferSize = 8;
}
if (maxFileSize < 1) {
maxFileSize = 1024 * 1024 * 1024 * 2L;
} else if (maxFileSize > Long.MAX_VALUE) {
maxFileSize = 1024 * 1024 * 1024 * 2L;
}
}
/**
*
function:根据传递InputStream,上传文件
* @createDate Dec 19, 2010 8:53:12 PM
* @param is InputStream
* @param fileName 文件名
* @param path 保存路径
* @return 上传状态
* @throws Exception
*/
public static UploadState upload4Stream(InputStream is, String fileName, String path) throws Exception {
init();
UploadState state = UploadState.UPLOAD_FAILURE;
if (fileName == null && "".equals(fileName)) {
fileName = getRandomName(fileName);
}
OutputStream os = null;
try {
path = getDoPath(path);
mkDir(path);
fileName = getBracketFileName(fileName, path);
os = new FileOutputStream(path + fileName);
int read = 0;
byte[] buffer = new byte[bufferSize];
while ((read = is.read(buffer)) != -1) {
os.write(buffer, 0, read);
}
state = UploadState.UPLOAD_SUCCSSS;
} catch(FileNotFoundException e) {
state = UploadState.UPLOAD_NOTFOUND;
throw e;
} catch (Exception e) {
state = UploadState.UPLOAD_FAILURE;
throw e;
} finally {
if (is != null) {
is.close();
}
if (os != null) {
os.flush();
os.close();
}
}
return state;
}
/**
*
function: 主要针对struts的FormFile进行文件上传
* @createDate Oct 9, 2010 11:22:14 PM
* @param file FormFile
* @param path 路径
* @return UploadState 是否上传成功
* @throws Exception
*/
public static UploadState upload(FormFile file, String fileName, String path) throws Exception {
init();
UploadState state = UploadState.UPLOAD_FAILURE;
if (fileName == null && "".equals(fileName)) {
fileName = file.getFileName();
}
InputStream is = null;
try {
long fileSize = file.getFileSize();
if (fileSize <= 0) {
state = UploadState.UPLOAD_ZEROSIZE;
} else {
if (fileSize <= maxFileSize) {
is = file.getInputStream();
state = upload4Stream(is, fileName, path);
} else {
state = UploadState.UPLOAD_OVERSIZE;
}
}
} catch(FileNotFoundException e) {
state = UploadState.UPLOAD_NOTFOUND;
throw e;
} catch (Exception e) {
state = UploadState.UPLOAD_FAILURE;
throw e;
} finally {
if (is != null) {
is.close();
}
}
return state;
}
/**
*
function:struts上传文件,并根据传递的文件类型数组验证上传的文件是否合法
* @createDate Oct 10, 2010 3:53:59 PM
* @param file FormFile
* @param path 路径
* @param allowTypes 文件类型数组
* @return UploadState 是否上传成功
* @throws Exception
*/
public static UploadState upload(FormFile file, String fileName, String path, String[] allowTypes) throws Exception {
UploadState state = UploadState.UPLOAD_FAILURE;
if (validTypeByName(file.getFileName(), allowTypes)) {
state = upload(file, fileName, path);
}
return state;
}
upload4Stream是通过传递InputStream完成上传,这个方法不管是是FormFile、File还是其他的文件对象都可以完成上传。你也可以根据自己的需求进行二次封装完成上传。
上面的上传还用到了其他的验证、命名、路径等辅助方法,详细请看源代码。
验证文件名、类型
/**
*
function: 根据文件名和类型数组验证文件类型是否合法,flag是否忽略大小写
* @createDate Oct 10, 2010 11:54:54 AM
* @param fileName 文件名
* @param allowTypes 类型数组
* @param flag 是否获得大小写
* @return 是否验证通过
*/
public static boolean validTypeByName(String fileName, String[] allowTypes, boolean flag) {
String suffix = getType(fileName);
boolean valid = false;
if (allowTypes.length > 0 && "*".equals(allowTypes[0])) {
valid = true;
} else {
for (String type : allowTypes) {
if (flag) {//不区分大小写后缀
if (suffix != null && suffix.equalsIgnoreCase(type)) {
valid = true;
break;
}
} else {//严格区分大小写
if (suffix != null && suffix.equals(type)) {
valid = true;
break;
}
}
}
}
return valid;
}
/**
*
function:根据文件名称和类型数组验证文件类型是否合法
* @createDate Oct 10, 2010 10:27:17 AM
* @param fileName 文件名
* @param allowTypes 文件类型数组
* @return 是否合法
*/
public static boolean validTypeByName(String fileName, String[] allowTypes) {
return validTypeByName(fileName, allowTypes, true);
}
/**
*
function: 根据后缀和类型数组验证文件类型是否合法,flag是否区分后缀大小写,true严格大小写
* @createDate Oct 10, 2010 12:00:10 PM
* @param suffix 后缀名
* @param allowTypes 文件类型数组
* @param flag 是否区分大小写
* @return 是否合法
*/
public static boolean validTypeByPostfix(String suffix, String[] allowTypes, boolean flag) {
boolean valid = false;
if (allowTypes.length > 0 && "*".equals(allowTypes[0])) {
valid = true;
} else {
for (String type : allowTypes) {
if (flag) {//不区分大小写后缀
if (suffix != null && suffix.equalsIgnoreCase(type)) {
valid = true;
break;
}
} else {//严格区分大小写
if (suffix != null && suffix.equals(type)) {
valid = true;
break;
}
}
}
}
return valid;
}
/**
*
function:根据文件后缀名和类型数组,验证文件类型是否合法
* @createDate Oct 10, 2010 10:25:32 AM
* @param suffix 后缀名
* @param allowTypes 类型数组
* @return 是否合法
*/
public static boolean validTypeByPostfix(String suffix, String[] allowTypes) {
return validTypeByPostfix(suffix, allowTypes, true);
}
/**
*
function:验证当前后缀、文件类型是否是图片类型
* typeImages 可以设置图片类型
* @createDate Oct 10, 2010 12:17:18 PM
* @param suffix 验证文件的后缀
* @return 是否合法
*/
public static boolean validTypeByPostfix4Images(String suffix) {
return validTypeByPostfix(suffix, typeImages);
}
/**
*
function:验证当前后缀、文件类型是否是非图片类型(常用办公文件类型)
* typeOthers 可以设置文件类型
* @createDate Oct 10, 2010 12:18:18 PM
* @param suffix 验证文件的后缀
* @return 是否合法
*/
public static boolean validTypeByPostfix4Others(String suffix) {
return validTypeByPostfix(suffix, typeOthers);
}
/**
*
function:验证当前文件名、文件类型是否是图片类型
* typeImages 可以设置图片类型
* @createDate Oct 10, 2010 12:19:18 PM
* @param fileName 验证文件的名称
* @return 是否合法
*/
public static boolean validTypeByName4Images(String fileName) {
return validTypeByName(fileName, typeImages);
}
/**
*
function:验证当前文件名称、文件类型是否是非图片类型(常用办公文件类型)
* typeOthers 可以设置文件类型
* @createDate Oct 10, 2010 12:21:22 PM
* @param fileName 验证文件的名称
* @return 是否合法
*/
public static boolean validTypeByName4Others(String fileName) {
return validTypeByName(fileName, typeOthers);
}
文件删除操作,对重名的文件可以删除或是替换
/**
*
function:传递一个路径和文件名称,删除该文件
* @createDate Oct 10, 2010 10:47:57 AM
* @param fileName 文件名称
* @param path 路径
* @return 是否删除成功
*/
public static boolean removeFile(String fileName, String path) {
boolean flag = false;
if (isFileExist(fileName, path)) {
File file = new File(getDoPath(path) + fileName);
flag = file.delete();
}
return flag;
}
/**
*
function:删除文件
* @createDate Oct 10, 2010 10:49:54 AM
* @param file 要删除的文件
* @return 是否删除成功
*/
public static boolean removeFile(File file) {
boolean flag = false;
if (file != null && file.exists()) {
flag = file.delete();
}
return flag;
}
获得文件类型、后缀、名称等操作
/**
*
function: 传入一个文件名,得到这个文件名称的后缀
* @createDate Oct 9, 2010 11:30:46 PM
* @param fileName 文件名
* @return 后缀名
*/
public static String getSuffix(String fileName) {
int index = fileName.lastIndexOf(".");
if (index != -1) {
String suffix = fileName.substring(index);//后缀
return suffix;
} else {
return null;
}
}
/**
*
function:和文件后缀一样,不同的是没有“.”
* @createDate Oct 10, 2010 2:42:43 PM
* @param fileName 文件名称
* @return
*/
public static String getType(String fileName) {
int index = fileName.lastIndexOf(".");
if (index != -1) {
String suffix = fileName.substring(index + 1);//后缀
return suffix;
} else {
return null;
}
}
/**
*
function: 传递一个文件名称和一个新名称,组合成一个新的带后缀文件名
* 当传递的文件名没有后缀,会添加默认的后缀
* @createDate Oct 9, 2010 10:53:06 PM
* @param fileName 文件名称
* @param newName 新文件名称
* @param nullSuffix 为没有后缀的文件所添加的后缀;eg:txt
* @return String 文件名称
*/
public static String getNewFileName(String fileName, String newName, String nullSuffix) {
String suffix = getSuffix(fileName);
if (suffix != null) {
newName += suffix;
} else {
newName = newName.concat(".").concat(nullSuffix);
}
return newName;
}
/**
*
function: 利用uuid产生一个随机的name
* @createDate Oct 9, 2010 10:45:27 PM
* @param fileName 带后缀的文件名称
* @return String 随机生成的name
*/
public static String getRandomName(String fileName) {
String randomName = UUID.randomUUID().toString();
return getNewFileName(fileName, randomName, "txt");
}
/**
*
function: 用当前日期、时间和1000以内的随机数组合成的文件名称
* @createDate Oct 9, 2010 11:01:47 PM
* @param fileName 文件名称
* @return 新文件名称
*/
public static String getNumberName(String fileName) {
SimpleDateFormat format = new SimpleDateFormat("yyMMddhhmmss");
int rand = new Random().nextInt(1000);
String numberName = format.format(new Date()) + rand;
return getNewFileName(fileName, numberName, "txt");
}
/**
*
function:判断该文件是否存在
* @createDate Oct 10, 2010 12:00:44 AM
* @param fileName 文件名称
* @param path 目录
* @return 是否存在
*/
public static boolean isFileExist(String fileName, String path) {
File file = new File(getDoPath(path) + fileName);
return file.exists();
}
/**
*
function:返回可用的文件名
* @createDate Oct 10, 2010 1:02:45 AM
* @param fileName 文件名
* @param path 路径
* @return 可用文件名
*/
public static String getBracketFileName(String fileName, String path) {
return getBracketFileName(fileName, fileName, path, 1);
}
/**
*
function:递归处理文件名称,直到名称不重复(对文件名、目录文件夹都可用)
* eg: a.txt --> a(1).txt
* 文件夹upload--> 文件夹upload(1)
* @createDate Oct 10, 2010 12:56:27 AM
* @param fileName 文件名称
* @param path 文件路径
* @param num 累加数字,种子
* @return 返回没有重复的名称
*/
public static String getBracketFileName(String fileName, String bracketName, String path, int num) {
boolean exist = isFileExist(bracketName, path);
if (exist) {
int index = fileName.lastIndexOf(".");
String suffix