消防器材厂家东莞网站建设东莞麻涌网站建设
消防器材厂家东莞网站建设,东莞麻涌网站建设,北京seo关键词排名优化软件,深圳市住房和建设局电话文件上传一个经常用到的功能#xff0c;它有许多中实现的方案。
页面表单 RFC1897规范 http协议上传
页面控件(flash/html5/activeX/applet) RFC1897规范 http协议上传
页面控件(flash/html5/activeX/applet) 自定义数据规范 http协议上传
页面控件(flash/html5/act…文件上传一个经常用到的功能它有许多中实现的方案。
页面表单 RFC1897规范 http协议上传
页面控件(flash/html5/activeX/applet) RFC1897规范 http协议上传
页面控件(flash/html5/activeX/applet) 自定义数据规范 http协议上传
页面控件(flash/html5/activeX/applet) FTP协议上传
页面控件(flash/html5/activeX/applet) 自定义协议 用apache common upload组件实际就是采用的“页面表单 RFC1897规范 http协议上传”实现方式需要实现的技术点
1. 多文件数据的提交
2. 文件数据包接收存储功能
3. 文件数据上传进度
4. WEB页面无刷新异步提交 时序图
文件上传时序图文件上传进度获取时序图
实现思路
1. 多文件数据的提交
在WEB页面采用多个input typefile利用form表单进行文件提交 2. 文件数据包接收存储功能
服务端采用servlet利用apache common upload组件接收解析数据包接收解析的过程中保存进度到session, 文件接收完毕后保存到指定目录 3. 文件数据上传进度
在WEB页面在界面写一个定时器定时访问服务器提供上传进度获取功能的servlet获取文件上传进度信息 4. WEB页面无刷新异步提交
利用iframe来实现WEB页面无刷新异步上传 关键代码
UploadFileServlet.java
Java代码 package com.test.servlet; import java.io.File; import java.io.IOException; import java.io.Writer; import java.util.Iterator; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.FileCleanerCleanup; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.io.FileCleaningTracker; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * 文件上传数据接收类 * * author chengqi * */ public class UploadFileServlet extends HttpServlet { /** 日志对象*/ private Log logger LogFactory.getLog(this.getClass()); private static final long serialVersionUID 1L; /** 上传目录名*/ private static final String uploadFolderName uploadFiles; /** 上传临时文件存储目录*/ private static final String tempFolderName tempFiles; /** 上传文件最大为30M*/ private static final Long fileMaxSize 30000000L; /** 允许上传的扩展名*/ private static final String [] extensionPermit {txt, xls, zip}; /** 统一的编码格式*/ private static final String encode UTF-8; Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { logger.info(UploadFileServlet#doPost() start); try { String curProjectPath this.getServletContext().getRealPath(/); String saveDirectoryPath curProjectPath / uploadFolderName; String tempDirectoryPath curProjectPath / tempFolderName; File saveDirectory new File(saveDirectoryPath); File tempDirectory new File(tempDirectoryPath); logger.debug(Project real path [ saveDirectory.getAbsolutePath() ]); //上传时产生的临时文件的默认保存目录 logger.debug(Temp files default save path [ System.getProperty(java.io.tmpdir) ]); DiskFileItemFactory factory new DiskFileItemFactory(); //DiskFileItemFactory中DEFAULT_SIZE_THRESHOLD10240表示如果上传文件大于10K则会产生上传临时文件 //上传临时文件的默认目录为java.io.tmpdir中保存的路径根据操作系统的不同会有区别 if(!tempDirectory.exists()) { tempDirectory.mkdir(); } //重新设置临时文件保存目录 factory.setRepository(tempDirectory); //设置文件清除追踪器文件上传过程中产生的临时文件会在 FileCleaningTracker fileCleaningTracker FileCleanerCleanup.getFileCleaningTracker(this.getServletContext()); factory.setFileCleaningTracker(fileCleaningTracker); ServletFileUpload upload new ServletFileUpload(factory); //设置文件上传进度监听器 FileProcessListener processListener new FileProcessListener(request.getSession()); upload.setProgressListener(processListener); // 设置文件上传的大小限制 upload.setFileSizeMax(fileMaxSize); // 设置文件上传的头编码如果需要正确接收中文文件路径或者文件名 // 这里需要设置对应的字符编码为了通用这里设置为UTF-8 upload.setHeaderEncoding(encode); //解析请求数据包 ListFileItem fileItems upload.parseRequest(request); //遍历解析完成后的Form数据和上传文件数据 for (IteratorFileItem iterator fileItems.iterator(); iterator.hasNext();) { FileItem fileItem iterator.next(); String fieldName fileItem.getFieldName(); String name fileItem.getName(); //如果为上传文件数据 if(!fileItem.isFormField()) { logger.debug(fieldName[ fieldName ] fileName[ name ] ); if(fileItem.getSize() 0) { String fileExtension FilenameUtils.getExtension(name); if(!ArrayUtils.contains(extensionPermit, fileExtension)) { throw new NoSupportExtensionException(No Support extension.); } String fileName FilenameUtils.getName(name); FileUtils.copyInputStreamToFile(fileItem.getInputStream(), new File(saveDirectory, fileName)); } } else { //Form表单数据 String value fileItem.getString(encode); logger.debug(fieldName[ value ] fieldValue[ fieldName ]); } } responseMessage(response, State.OK); } catch(FileSizeLimitExceededException e) { logger.error(e.getMessage(), e); responseMessage(response, State.OVER_FILE_LIMIT); } catch(NoSupportExtensionException e) { logger.error(e.getMessage(), e); responseMessage(response, State.NO_SUPPORT_EXTENSION); } catch(Exception e) { logger.error(e.getMessage(), e); responseMessage(response, State.ERROR); } finally { //清除上传进度信息 request.getSession().removeAttribute(fileUploadProcess); } logger.info(UploadFileServlet#doPost() end); } public enum State { OK(200, 上传成功), ERROR(500, 上传失败), OVER_FILE_LIMIT(501, 超过上传大小限制), NO_SUPPORT_EXTENSION(502, 不支持的扩展名); private int code; private String message; private State(int code, String message) { this.code code; this.message message; } public int getCode() { return code; } public String getMessage() { return message; } } /** * 返回结果函数 * param response * param state */ private void responseMessage(HttpServletResponse response, State state) { response.setCharacterEncoding(encode); response.setContentType(text/html; charset encode); Writer writer null; try { writer response.getWriter(); writer.write(script); writer.write(window.parent.fileUploadCallBack({\code\: state.getCode() ,\message\:\ state.getMessage() \});); writer.write(/script); writer.flush(); writer.close(); } catch(Exception e) { logger.error(e.getMessage(), e); } finally { IOUtils.closeQuietly(writer); } } } GetFileProcessServlet.java
Java代码 package com.test.servlet; import java.io.IOException; import java.io.Writer; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * 文件上传进度获取Servlet * * author chengqi * */ public class GetFileProcessServlet extends HttpServlet { /** 日志对象*/ private Log logger LogFactory.getLog(this.getClass()); private static final long serialVersionUID 1L; Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { logger.info(GetFileProcessServlet#doGet start); String fileUploadPercent (String)request.getSession().getAttribute(fileUploadProcess); Writer writer null; try { writer response.getWriter(); logger.info(percent: fileUploadPercent); IOUtils.write(fileUploadPercent null ? 0% : fileUploadPercent, writer); writer.flush(); writer.close(); } catch(Exception e) { logger.error(e.getMessage(), e); } finally { IOUtils.closeQuietly(writer); } logger.info(GetFileProcessServlet#doGet end); } } FileProcessListener.java
Java代码 package com.test.servlet; import java.text.NumberFormat; import javax.servlet.http.HttpSession; import org.apache.commons.fileupload.ProgressListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * 文件进度监听器 * * author chengqi * */ public class FileProcessListener implements ProgressListener{ /** 日志对象*/ private Log logger LogFactory.getLog(this.getClass()); private HttpSession session; public FileProcessListener(HttpSession session) { this.session session; } public void update(long pBytesRead, long pContentLength, int pItems) { double readByte pBytesRead; double totalSize pContentLength; if(pContentLength -1) { logger.debug(item index[ pItems ] pBytesRead bytes have been read.); } else { logger.debug(item index[ pItems ] pBytesRead of pContentLength bytes have been read.); String p NumberFormat.getPercentInstance().format(readByte / totalSize); session.setAttribute(fileUploadProcess, p); } } } apacheUploadDemo.html Html代码 !DOCTYPE html PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN http://www.w3.org/TR/html4/loose.dtd html head titleApache common实现基本文件上传/title meta http-equivContent-Type contenttext/html; charsetUTF-8 script typetext/javascript srcjs/jquery/jquery-1.9.1.js/script script typetext/javascript srcjs/jquery/jquery.form.js/script script typetext/javascript //定时器对象 var uploadProcessTimer null; $(function (){ //绑定定时器开始操作到提交按钮 $(input[typesubmit]).click(function () { //启动上传进度查询定时器 uploadProcessTimer window.setInterval(getFileUploadProcess, 20); }) }); //获取文件上传进度 function getFileUploadProcess() { $.get(/upload/getFileProcessServlet, function(data) { $(#fileUploadProcess).html(data); }); } //上传完成后由iframe返回脚本自动调用 function fileUploadCallBack(res) { //清除定时器 if(uploadProcessTimer) { window.clearInterval(uploadProcessTimer); } var message res[message]; var code res[code]; if(code ! 200) { $(#fileUploadProcess).html(0%); } alert(message); } /script /head body h2上传文件1/h2 用户信息 br/ form idtestForm action/upload/uploadServlet methodpost enctypemultipart/form-data targetiframeUpload 姓名input namename typetext br/ 附件1input namefile1 typefile br/ 附件2input namefile2 typefile br/ brbr input typesubmit value提交 br/ /form 上传进度label idfileUploadProcess/label iframe nameiframeUpload src width350 height35 frameborder0 SCROLLINGno styledisplay:NONE/iframe /body /html 总结
虽然使用apache common upload组件实现了文件上传但是从上传的效果来看并不是一个很完美的解决方案。
有如下缺点
1. 当有多个文件上传时无法知道单个文件的上传进度因为文件上传消息中根本就没有关于单个文件大小的信息
文件上传消息
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Content-Type: text/html;charsetUTF-8 Transfer-Encoding: chunked Date: Tue, 22 Apr 2014 07:45:45 GMT POST /upload/uploadServlet HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0 Accept: text/html,application/xhtmlxml,application/xml;q0.9,*/*;q0.8 Accept-Language: zh-cn,zh;q0.8,en-us;q0.5,en;q0.3 Accept-Encoding: gzip, deflate Referer: http://localhost:8080/upload/apacheUploadDemo.html Cookie: JSESSIONID33498CE814284D67F957CA53D45F0174 Connection: keep-alive Content-Length 2363 Content-Type multipart/form-data; boundary---------------------------189163093917262 -----------------------------189163093917262 Content-Disposition: form-data; namename -----------------------------189163093917262 Content-Disposition: form-data; namefile1; filenameNew Text Document.txt Content-Type: text/plain 文件数据 -----------------------------189163093917262 Content-Disposition: form-data; namefile2; filenameNew Text Document (2).txt Content-Type: text/plain 文件数据 -----------------------------189163093917262-- 2. 浏览器必须将所有文件读取完毕才开始上传并且是一次性提交所有的数据文件在互联网环境下会http连接超时大文件无法上传成功。 3. 服务端判断是否超过大小限制是通过计算接收数据的累积字节数和限制大小比较这种情况下如果限制大小是30M那么在服务端已经读取了30M完成后才会抛出异常多余的消耗的服务器的内存和硬盘空间 所以基于这些原因页面表单 RFC1897规范 http协议上传 后台apache common upload组件接收的这种解决方案不适合解决WEB页面一次多文件上传大文件上传情况比较适合一次单个小文件附件的情况如博客附件登记照片上传预览等情况。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/92528.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!