最近做一个项目,需要将txt、jpg图片等文件批量读入服务器的数据库中。用到了swfupload插件。
项目要求文件需要批量上传,但不能有重复上传,分析出来就是:批量上传文件,上传过程中将文件读入数据库,如果文件入库成功,则返回成功信息;如果入库失败,则返回失败信息(文件错误或文件重复上传)。
一、准备:
下载swfupload插件,SWFUpload v2.2.0.1 Core.zip(http://www.swfupload.org/),并取下载文件中的SWFUpload.js和swfupload.swf文件。
swfupload.swf是上传组件的核心,一个特制的FLASH,具有浏览文件,上传文件的功能,以按钮形式体现在用户眼前。SWFUpload.js与swfupload.swf交互,向开发者提供操作接口。
二、文件部署:
将SWFUpload.js与swfupload.swf及用到的其他图片等文件部署到web项目中(此例IDE用myeclipse),
当然,要写好项目需要的txtupload.jsp、txtuploadaction等。txtupload.jsp是用户上传页面;txtuploadaction是对应的action,功能是读取文件并读入数据库。web项目只需用到他们俩及上面提到的swfupload组件就可以实现批量文件上传入库并返回上传信息。
三、jsp页面引入swfupload
在txtupload.jsp文件中写入
<script type="text/javascript" src="swfupload.js"></script>
此时,需要新建一个JS文件,专门用来存放捕获事件函数,此例为handlers.js,并引入
<script type="text/javascript" src="handlers.js"></script>
将swfupload组建实例化:
upload1 = new SWFUpload({
// Backend Settings
upload_url: "TxtUploadAction.action",
post_params: {"picSESSID" : "songhao"},
file_post_name: "file", //上传到服务器的文件name,默认为filedata
// File Upload Settings
file_size_limit : "1024", // 限制上传大小1MB
file_types : "*.txt;*.TXT;",//限制上传文件类型
file_types_description : "TXT Files",
file_upload_limit : "0",
file_queue_limit : "0",
// Event Handler Settings (all my handlers are in the Handler.js file)
file_dialog_start_handler : fileDialogStart,
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,// Button Settings
button_image_url : "images/XPButtonUploadText_61x22.png",
button_placeholder_id : "spanButtonPlaceholder1",
button_width: 61,
button_height: 22,
// Flash Settings
flash_url : "js/swfupload.swf",
custom_settings : {
progressTarget : "fsUploadProgress1",
cancelButtonId : "btnCancel1"
},
// Debug Settings
debug: false
});
将实例添加到表单:
<form action="TxtUploadAction" method="post" name="thisform" enctype="multipart/form-data">
<p>The TXTupload page .</p>
<table>
<tr valign="top">
<td>
<div>
<div class="fieldset flash" id="fsUploadProgress1">
<span class="legend">TXT File Upload Site</span>
</div>
<div style="padding-left: 5px;">
<span id="spanButtonPlaceholder1"></span>
<input id="btnCancel1" type="button" value="Cancel Uploads" οnclick="cancelQueue(upload1);" disabled="disabled" style="margin-left: 2px; height: 22px; font-size: 8pt;" />
<br />
</div>
</div>
</td>
</tr>
</table>
</form>
四、编写Action
根据上面对swfupload实例化的修改,txt文件上传后,服务器得到的name将是"file"。写action如下:
package com.action;
import java.io.File;
import java.sql.Connection;
import java.util.List;
import com.common.DBcon;
import com.opensymphony.xwork2.ActionSupport;
public class TxtUploadAction extends ActionSupport {
/**
*
*/
private static final long serialVersionUID = 1L;
private File file;
private String fileFileName;
private String fileContentType;
private String uploadtag=null;//标记文件是否入库成功
public String getUploadtag() {
return uploadtag;
}
public void setUploadtag(String uploadtag) {
this.uploadtag = uploadtag;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public String getFileFileName() {
return fileFileName;
}
public void setFileFileName(String fileFileName) {
this.fileFileName = fileFileName;
}
public String getFileContentType() {
return fileContentType;
}
public void setFileContentType(String fileContentType) {
this.fileContentType = fileContentType;
}
/**
*
*/
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
//
boolean flag=false;
Connection conn = DBcon.getConnection();// 这是用来连通数据库,记得,要下载个驱动程序,sql server
txtImport t=new txtImport();//txtImport类来处理文件入库操作,并有返回值
flag=t.readfile(fileFileName,file.getAbsolutePath(), conn);
if(flag)
{
uploadtag=fileFileName+"上传成功";
}else
{
uploadtag=fileFileName+"上传失败,请确认上传文件正确且无重复上传";
}
return "convert";
}
}
五、将Action返回值由swfupload返回给用户
这里是难点。
在上传文件时,我们发现上传成功事件对应的内置函数为handlers.js中uploadSuccess(file object, server data, received response),其中第一个参数为上传的文件,第二个参数为服务器返回的数据。struts2跳转的页面以HTML代码形式赋值给第二个参数,故可在该捕获事件函数中,置入document.write(server_data)语句,即实现页面跳转。但如果是这样,swfupload将上传成功一个文件,就页面跳转,而且swfupload中文件队列丢失,这就成了单个文件上传,失去批量上传功能。
uploadSuccess是每次文件上传成功后调用的函数,而uploadComplete是文件上传完毕后调用的函数,不管成功与失败,它位于uploadSuccess完成后调用。
1,添加一个全局数据var serverdatas=new Array();来存入每次uploadSuccess的server data。
2,在uploadSuccess中,将serverData存入serverdatas,以将其保存到最后全部文件上传完毕并跳转页面之时。serverdatas.push(serverData);
3,在uplodaComplete中做判断,如果files_queued为0,即上传队列数为0,则执行页面跳转,当然我们要将server。
if (this.getStats().files_queued === 0) {
document.getElementById(this.customSettings.cancelButtonId).disabled = true;
var i;
for(i=0;i<serverdatas.length;i++){
document.write(serverdatas[i]);
}
}
这样,就完成了全部操作,测试成功。
注意:此页面跳转为js跳转而非action的返回跳转。