SWFUpload详解 java后台接收实例(包括传参问题)
来源:互联网 发布:怎么免费装修淘宝店铺 编辑:程序博客网 时间:2024/06/05 08:31
一、简介和示例
SWFUpload is a small JavaScript/Flash library to get the best of both worlds. It features the great upload capabilities of Flash and the accessibility and ease of HTML/CSS。
官方站点:http://www.swfupload.org/
简单来说,swfupload这个上传库是可以显示上传进度以及上传速度等上传信息。一般实现这种上传体验有2种方式,一种是异步上传,在服务器端边接收数据边往session写入接收的字节数和进度数据,然后客户端轮询这个记录在session的进度数据并回显到页面。第二种方式就是采用flash来上传,也就是swfupload所采用的方式,在发送过程中将发送的相关状态数据回传到js的函数中处理。
二、参数说明
原理是很明显易懂的,关键是flash和javascript的通讯部分,在文件上传的各个状态都会有javascript和flash函数的相互回调。目前主要研究了上传单个文件的上传逻辑,swfupload支持多个文件上传的,不过核心的逻辑应该是没有太多的变化。swfupload用一个队列来管理多个文件上传的,因为在传入的参数中会有一些队列和文件上传数量相关的参数。
在其核心的JavaScript文件swfupload.js定义的状态码以及从flash传递到js的文件对象:
//文件对象file = { "id":SWFUpload_0_0, "index":0, "filestatus":-1, "name":vim-cheat-sheet-diagram.png, "size":317949, "type":"", "creationdate":Fri Jan 16 1970 00:08:13 GMT+0800 (CST), "modficationdate":Fri Jan 16 1970 00:08:13 GMT+0800 (CST), "post": {}}//文件队列错误码SWFUpload.QUEUE_ERROR = { QUEUE_LIMIT_EXCEEDED : -100, FILE_EXCEEDS_SIZE_LIMIT : -110, ZERO_BYTE_FILE : -120, INVALID_FILETYPE : -130};//上传错误码SWFUpload.UPLOAD_ERROR = { HTTP_ERROR : -200, MISSING_UPLOAD_URL : -210, IO_ERROR : -220, SECURITY_ERROR : -230, UPLOAD_LIMIT_EXCEEDED : -240, UPLOAD_FAILED : -250, SPECIFIED_FILE_ID_NOT_FOUND : -260, FILE_VALIDATION_FAILED : -270, FILE_CANCELLED : -280, UPLOAD_STOPPED : -290};//文件状态SWFUpload.FILE_STATUS = { QUEUED : -1, IN_PROGRESS : -2, ERROR : -3, COMPLETE : -4, CANCELLED : -5};//按钮的动作SWFUpload.BUTTON_ACTION = { SELECT_FILE : -100, SELECT_FILES : -110, START_UPLOAD : -120};
1. 事件处理函数
事件函数触发时间参数swfupload_loaded_handler在flash初始化完成之后没有参数file_dialog_start_handler当用户点击上传按钮,在打开文件浏览窗口之前没有参数file_queued_handler用户成功地选择了文件,在file_dialog_complete_handler事件之前触发。如果选择了多个文件,则触发多次file文件对象file_queue_error_handler文件上传数量、类型、大小不符合时file文件对象、错误码、从flash中返回的错误信息file_dialog_complete_handler在用户成功了选择了文件后,在所有file_queued_handler之后触发选择文件的数量、加入了文件队列的文件数量、在当前文件队列总共的文件数量upload_start_handler用户点击了提交按钮,开始把文件上传到服务器file文件对象upload_progress_handler刚打开与服务器的连接与文件上传过程中file文件对象、已经上传的字节数、总共要上传的字节数upload_error_handler上传失败时file文件对象、错误码、从flash中返回的错误信息upload_success_handler文件上传成功或者等待服务器数据返回超时file文件对象、服务器返回的数据、服务器是否有返回数据upload_complete_handler上传完成时,在upload_success_handler之后触发file文件对象debug_handler调用SWFUpload对象的debug()函数时swfupload对象和其初始化的参数2. 其他重要参数
参数名意义说明upload_url要上传到的服务器地址 file_post_name上传到服务器中文件内容对应的key flash_urlflash元素的url custom_settings自定义的参数,可以在事件处理函数中获取得到dict类型button_placeholder_idflash的上传按钮显示在html的位置,此名称的元素会被替换成object元素span即可三、上传逻辑
下面是用graphviz画出来的流程图,图比较大,不过看得舒服:)
1. 如上面的示例代码所示,在javascript代码中首先要创建一个SWFUpload的javascript对象,这个对象创建的初始化逻辑如下(箭头表示逻辑和流程的走向):
2. 当javascript将object元素添加到html页面的元素中时,即初始化flash中的元素:
3.用户点击上传的按钮,准备选择文件时,这个已经绑定了按钮的点击事件,而这个按钮不是input而是一个flash的元素:
4.用户选择完文件后:
5. 用户点击提交按钮,文件开始上传到服务器:
6. 文件上传过程中的一些事件处理逻辑:
实例代码(注意要在服务器部署之后下浏览才有效)
上代码:
一、前台页面index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%><%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>文件上传swfupload使用</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <link href="<%=basePath%>css/default.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="<%=basePath%>swfupload/swfupload.js"></script> <script type="text/javascript" src="<%=basePath%>swfupload/swfupload.queue.js"></script> <script type="text/javascript" src="<%=basePath%>js/fileprogress.js"></script> <script type="text/javascript" src="<%=basePath%>js/handlers.js"></script> <script type="text/javascript"> var swfu; window.onload = function () { var settings = { flash_url : "<%=basePath%>swfupload/swfupload.swf", flash9_url : "<%=basePath%>swfupload/swfupload_fp9.swf", upload_url: "<%=basePath%>upload", post_params: { "hello" : "Here I Am", "name" : "张三" }, file_size_limit : "100 MB", file_types : "*.*", file_types_description : "All Files", file_upload_limit : 100, file_queue_limit : 0, custom_settings : { progressTarget : "fsUploadProgress", cancelButtonId : "btnCancel" }, debug: true, use_query_string : true,//要传递参数,必须配置,可以从后台取到参数,应该还有其他方式,如post方式,未了解 // Button Settings button_image_url : "<%=basePath%>images/TestImageNoText_65x29.png", button_placeholder_id : "spanButtonPlaceholder", button_width: 61, button_height: 22, button_text: '浏览', button_text_style: ".spanButtonPlaceholder { font-size: 12; }", button_text_left_padding: 12, button_text_top_padding: 3, // The event handler functions are defined in handlers.js //swfupload_preload_handler : preLoad, //swfupload_load_failed_handler : loadFailed, 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 // Queue plugin event }; swfu = new SWFUpload(settings); } </script> </head> <body> <div class="fieldset flash" id="fsUploadProgress"> <span class="legend">文件列表:</span> </div> <div id="divStatus">上传了0个文件</div> <div class="flash" id="fsUploadProgress"> </div> <div style="padding-left: 5px;"> <span id="spanButtonPlaceholder"></span> <input id="btnCancel" type="button" value="取消" onclick="cancelQueue(upload);" disabled="disabled" style="margin-left: 2px; height: 22px; font-size: 8pt;" /> </div> <!-- 上传文件列表 --> <div class="fileList" id="fileList"> </div> </body></html>二、前台接收后台返回数据的位置 --handler.js-只需要找到该位置,进行修改就可以了
function uploadSuccess(file, serverData) { try { var progress = new FileProgress(file, this.customSettings.progressTarget); progress.setComplete(); progress.setStatus("上传完成."); progress.toggleCancel(false); alert(serverData); //后台传递回来的内容 var serdata = document.getElementById("fileList"); serdata.innerHTML = serverData; } catch (ex) { this.debug(ex); }}三、后台servlet-Upload.java,下边只列出了用到的doPost()方法,其他内容都没有变化
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //接收参数 String hello = request.getParameter("hello"); String name = request.getParameter("name"); name = new String(name.getBytes("ISO-8859-1"),"UTF-8");//字符编码问题,可以通过前台encoding后台再解析 System.out.println("接收参数,hello="+hello+",name="+name); String path1 = request.getRequestURI()+"/files"; System.out.println("____________request.getRequestURI():"+path1); String path2 = request.getSession().getServletContext().getRealPath("/"); System.out.println("_________path2:"+path2); List<FileEntity> fileList; fileList = (List)request.getAttribute("fileList"); if(fileList==null) fileList = new ArrayList<FileEntity>(); //接收上传文件 String uploadSign = request.getParameter("upload"); String rootPath = request.getParameter("rootPath"); String path = request.getParameter("path"); if(rootPath == null) rootPath = ""; rootPath = rootPath.trim(); if(rootPath.equals("")){ //rootPath = application.getRealPath("/swfupload/files");//自由修改处二:指定服务器固定文件 rootPath = path2+"/files"; } if(path == null) { path = rootPath; }else{ path = new String(Base64.decodeBase64(path.getBytes())); } System.out.println(path+"...path.getBytes():"+path.getBytes()); uploadSign = "1"; //上传操作 if(null != uploadSign && !"".equals(uploadSign)){ FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); //upload.setHeaderEncoding("UTF-8"); try{ List items = upload.parseRequest(request); if(null != items){ Iterator itr = items.iterator(); int i = 0; while(itr.hasNext()){ FileItem item = (FileItem)itr.next(); FileEntity file = new FileEntity();//_____________________ if(item.isFormField()){ continue; }else{ //自由修改处三:可修改上传后的文件命名方式 SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddkkmmss");//以当前精确到秒的日期为上传的文件的文件名 SimpleDateFormat sdd=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String type = item.getName().split("\\.")[1];//获取文件类型 System.out.println("——————————————————文件名称:"+item.getName()); System.out.println("从GBK转到UTF-8输出:"+new String(item.getName().getBytes("GBK"),"UTF-8")); File savedFile = new File(path,sdf.format(new Date())+"."+type); //把文件放到列表中,在前台显示 System.out.println("__________________服务器上对应的文件名称:"+sdf.format(new Date())+"."+type); System.out.println("__________________完整路径:"+path1+"/"+sdf.format(new Date())+"."+type); file.setId(sdf.format(new Date())); file.setDate(sdd.format(new Date())); file.setFilename(item.getName()); file.setFilepath(path1+"/"+sdf.format(new Date())+"."+type); file.setFilesize(item.getSize()+""); file.setFiletype(type); file.setMark("0"); fileList.add(file); item.write(savedFile); } } } }catch(Exception e){ e.printStackTrace(); } } response.setContentType("text/html"); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); if(fileList!=null){ for(int i=0;i<fileList.size();i++){ FileEntity file = (FileEntity)fileList.get(i); //out.println("文件:"+ new String(file.getFilename().getBytes("GBK"),"UTF-8")+",文件路径:"+file.getFilepath()); out.println("文件:"+ new String(file.getFilename().getBytes("GBK"),"UTF-8")+",上传成功!"); } } }四、自定义的一个文件类FileEntity.java,测试时全部用的String类型
package com.swfupload.entity;public class FileEntity { private String id; private String belong; private String filename; private String filepath; private String filetype; private String filesize; private String date; private String mark; public FileEntity(){} public String getId() { return id; } public void setId(String id) { this.id = id; } public String getBelong() { return belong; } public void setBelong(String belong) { this.belong = belong; } public String getFilename() { return filename; } public void setFilename(String filename) { this.filename = filename; } public String getFilepath() { return filepath; } public void setFilepath(String filepath) { this.filepath = filepath; } public String getFiletype() { return filetype; } public void setFiletype(String filetype) { this.filetype = filetype; } public String getFilesize() { return filesize; } public void setFilesize(String filesize) { this.filesize = filesize; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getMark() { return mark; } public void setMark(String mark) { this.mark = mark; } public static void main(String[] agrs){ String str=""; System.out.println(str); }}
- SWFUpload详解 java后台接收实例(包括传参问题)
- CKEditor+SWFUpload实现功能较为强大的编辑器(三)---后台接收图片流程
- Ajax向java后台中传值为数组时,后台接收不到(为null)的问题
- Ajax向java后台中传值为数组时,后台接收不到(为null)的问题
- base64编码上传图片java后台接收实例
- java后台接收数据
- ajax接收java后台传过来的json数据乱码及获取字段undefind问题
- 后台接收前台 String json 取单个值问题-java
- swfupload详解
- SWFUpload详解
- SWFUpload详解
- SWFUpload 详解
- js中关于get请求(包括异步以及直接用过网页连接请求),后台接收乱码问题
- WEB后台--邮件和短信业务实现(包括Java一键实现、封装和异步)以及原理详解
- WEB后台--邮件和短信业务实现(包括Java一键实现、封装和异步)以及原理详解
- 利用WebBrowser彻底解决Web打印问题(包括后台打印)
- 利用WebBrowser彻底解决Web打印问题(包括后台打印)
- 利用WebBrowser彻底解决Web打印问题(包括后台打印)
- js 调用不同的js函数列表的时候, 中间需要时间间隔
- ifconfig 与永久修改MAC地址
- POJ 2942(Tarjen的点双连通分量+交叉染色法)
- ClientdataSet 三层中主从表的操作
- 关于rsync
- SWFUpload详解 java后台接收实例(包括传参问题)
- windbg 调试 win7
- C语言中static的作用
- gdb中常用的一些命令
- 两分钟彻底让你明白Android Activity生命周期
- 程序员编程技术迅速提高的终极攻略
- Android Message 及其使用
- 苹果三星好“基友”:专利诉讼不影响元件供应
- Eclipse 自动添加注释