最近使用jeesite框架,需要上传功能,机缘巧合使用了Jquery File Upload插件(以下简称JFU)。
首先下载JFU解压缩后里面自带demo,以jquery-ui.html这个demo为例,我经过测试上传发现上传时的进度条有明显缺陷这里我将他隐藏。将无用处的内容删除,注意demo里有部分CSS/JS链接指向外部网站这里我将它们统统下载至本地,令修改了“template-download”模板增加一个隐藏的input用于记录文件id。代码如下所示:
<!DOCTYPE HTML> <html lang="zh"> <head> <!-- Force latest IE rendering engine or ChromeFrame if installed --> <!--[if IE]> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <![endif]--> <meta charset="utf-8"> <title>上传测试</title> <meta name="description" content="File Upload widget with multiple file selection, drag&drop support, progress bars, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads."> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- jQuery UI styles --> <link rel="stylesheet" href="css/jquery-ui2.css" id="theme"> <!-- Demo styles --> <!--[if lte IE 8]> <link rel="stylesheet" href="css/demo-ie8.css"> <![endif]--> <style> /* Adjust the jQuery UI widget font-size: */ .ui-widget { font-size: 0.95em; } </style> <!-- blueimp Gallery styles --> <link rel="stylesheet" href="css/blueimp-gallery.min.css"> <!-- CSS to style the file input field as button and adjust the Bootstrap progress bars --> <!-- Demo styles --> <link rel="stylesheet" href="css/demo.css"> <link rel="stylesheet" href="css/jquery.fileupload.css"> <link rel="stylesheet" href="css/jquery.fileupload-ui.css"> <!-- CSS adjustments for browsers with JavaScript disabled --> <noscript><link rel="stylesheet" href="css/jquery.fileupload-noscript.css"></noscript> <noscript><link rel="stylesheet" href="css/jquery.fileupload-ui-noscript.css"></noscript> </head> <body> <!-- The file upload form used as target for the file upload widget --> <form id="fileupload" action="//jquery-file-upload.appspot.com/" method="POST" enctype="multipart/form-data"> <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload --> <div class="fileupload-buttonbar"> <div class="fileupload-buttons"> <!-- The fileinput-button span is used to style the file input field as button --> <span class="fileinput-button"> <span>添加文件</span> <input type="file" name="files[]" multiple> </span> <button type="submit" class="start">开始上传</button> <button type="reset" class="cancel">取消上传</button> <button type="button" class="delete">删除</button> <input type="checkbox" class="toggle"> <!-- The global file processing state --> <span class="fileupload-process"></span> </div> <!-- The global progress state --> <div class="fileupload-progress fade" style="display:none"> <!-- The global progress bar --> <div class="progress" role="progressbar" aria-valuemin="0" aria-valuemax="100"></div> <!-- The extended global progress state --> <div class="progress-extended"> </div> </div> </div> <!-- The table listing the files available for upload/download --> <table role="presentation"><tbody class="files"> <tr class="template-download fade" style=""> <td> <span class="preview"> </span> </td> <td> <p class="name"> <a href="upload?getfile=load-image.all.min.js" title="load-image.all.min.js" download="load-image.all.min.js">回显测试</a> <input name="files" value="38c2ec65-841e-4cbf-a34b-f30a026773ec" type="hidden"> </p> </td> <td> <span class="size">17.77 KB</span> </td> <td> <button class="delete ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-primary" data-type="" data-url="" role="button"><span class="ui-button-icon-primary ui-icon ui-icon-trash"></span><span class="ui-button-text">Delete</span></button> <input name="delete" value="1" class="toggle" type="checkbox"> </td> </tr> <tr class="template-download fade" style=""> <td> <span class="preview"> </span> </td> <td> <p class="name"> <a href="upload?getfile=HTML2JS.exe" title="HTML2JS.exe" download="HTML2JS.exe">HTML2JS.exe</a> <input name="files" value="d44bf3db-d79c-480e-8e04-b15847863c27" type="hidden"> </p> </td> <td> <span class="size">11.78 KB</span> </td> <td> <button class="delete ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-primary" data-type="" data-url="" role="button"><span class="ui-button-icon-primary ui-icon ui-icon-trash"></span><span class="ui-button-text">Delete</span></button> <input name="delete" value="1" class="toggle" type="checkbox"> </td> </tr> </tbody></table> </form> <!-- The template to display files available for upload --> <script id="template-upload" type="text/x-tmpl"> {% for (var i=0, file; file=o.files[i]; i++) { %} <tr class="template-upload fade"> <td> <span class="preview"></span> </td> <td> <p class="name">{%=file.name%}</p> <strong class="error"></strong> </td> <td> <p class="size">Processing...</p> <div class="progress" style="display:none;"></div> </td> <td> {% if (!i && !o.options.autoUpload) { %} <button class="start" disabled>Start</button> {% } %} {% if (!i) { %} <button class="cancel">Cancel</button> {% } %} </td> </tr> {% } %} </script> <!-- The template to display files available for download --> <script id="template-download" type="text/x-tmpl"> {% for (var i=0, file; file=o.files[i]; i++) { %} <tr class="template-download fade"> <td> <span class="preview"> {% if (file.thumbnailUrl) { %} <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" data-gallery><img src="{%=file.thumbnailUrl%}"></a> {% } %} </span> </td> <td> <p class="name"> <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" {%=file.thumbnailUrl?'data-gallery':''%}>{%=file.name%}</a> <input type="hidden" name="files" value="{%=file.fileid%}" > </p> {% if (file.error) { %} <div><span class="error">Error</span> {%=file.error%}</div> {% } %} </td> <td> <span class="size">{%=o.formatFileSize(file.size)%}</span> </td> <td> <button class="delete" data-type="{%=file.deleteType%}" data-url="{%=file.deleteUrl%}"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{"withCredentials":true}'{% } %}>Delete</button> <input type="checkbox" name="delete" value="1" class="toggle"> </td> </tr> {% } %} </script> <script src="../bootstrap3/js/jquery-1.11.3.min.js"></script> <script src="js/jquery-ui.js"></script> <!-- The Templates plugin is included to render the upload/download listings --> <script src="js/tmpl.min.js"></script> <!-- The Load Image plugin is included for the preview images and image resizing functionality --> <script src="js/load-image.all.min.js"></script> <!-- The Canvas to Blob plugin is included for image resizing functionality --> <script src="js/canvas-to-blob.min.js"></script> <!-- blueimp Gallery script --> <script src="js/jquery.blueimp-gallery.min.js"></script> <!-- The Iframe Transport is required for browsers without support for XHR file uploads --> <script src="js/jquery.iframe-transport.js"></script> <!-- The basic File Upload plugin --> <script src="js/jquery.fileupload.js"></script> <!-- The File Upload processing plugin --> <script src="js/jquery.fileupload-process.js"></script> <!-- The File Upload image preview & resize plugin --> <script src="js/jquery.fileupload-image.js"></script> <!-- The File Upload audio preview plugin --> <script src="js/jquery.fileupload-audio.js"></script> <!-- The File Upload video preview plugin --> <script src="js/jquery.fileupload-video.js"></script> <!-- The File Upload validation plugin --> <script src="js/jquery.fileupload-validate.js"></script> <!-- The File Upload user interface plugin --> <script src="js/jquery.fileupload-ui.js"></script> <!-- The File Upload jQuery UI plugin --> <script src="js/jquery.fileupload-jquery-ui.js"></script> <!-- The main application script --> <script src="js/main.js"></script> <!-- The XDomainRequest Transport is included for cross-domain file deletion for IE 8 and IE 9 --> <!--[if (gte IE 8)&(lt IE 10)]> <script src="js/cors/jquery.xdr-transport.js"></script> <![endif]--> </body> </html>
修改jquery.fileupload-ui.js里面的getFilesFromResponse方法,修改了返回值为return data.result,这里非常关键。
最后servlet代码如下所示:
package com.thinkgem.jeesite.JFupload.web; import java.awt.image.BufferedImage; import java.io.*; import java.util.List; import java.util.UUID; import javax.imageio.ImageIO; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; 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.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.imgscalr.Scalr; import org.json.JSONArray; import org.json.JSONObject; public class UploadServlet extends HttpServlet { // private static final long serialVersionUID = 1L; private File fileUploadPath; @Override public void init(ServletConfig config) { String path = config.getServletContext().getRealPath("/"); fileUploadPath = new File(path+config.getInitParameter("upload_path")); } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) * */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if (request.getParameter("getfile") != null && !request.getParameter("getfile").isEmpty()) { File file = new File(fileUploadPath, request.getParameter("getfile")); if (file.exists()) { int bytes = 0; ServletOutputStream op = response.getOutputStream(); response.setContentType(getMimeType(file)); response.setContentLength((int) file.length()); response.setHeader( "Content-Disposition", "inline; filename=\"" + file.getName() + "\"" ); byte[] bbuf = new byte[1024]; DataInputStream in = new DataInputStream(new FileInputStream(file)); while ((in != null) && ((bytes = in.read(bbuf)) != -1)) { op.write(bbuf, 0, bytes); } in.close(); op.flush(); op.close(); } } else if (request.getParameter("delfile") != null && !request.getParameter("delfile").isEmpty()) { File file = new File(fileUploadPath, request.getParameter("delfile")); if (file.exists()) { file.delete(); // TODO:check and report success } } else if (request.getParameter("getthumb") != null && !request.getParameter("getthumb").isEmpty()) { File file = new File(fileUploadPath, request.getParameter("getthumb")); if (file.exists()) { String mimetype = getMimeType(file); if (mimetype.endsWith("png") || mimetype.endsWith("jpeg") || mimetype.endsWith("gif")) { BufferedImage im = ImageIO.read(file); if (im != null) { BufferedImage thumb = Scalr.resize(im, 75); ByteArrayOutputStream os = new ByteArrayOutputStream(); if (mimetype.endsWith("png")) { ImageIO.write(thumb, "PNG" , os); response.setContentType("image/png"); } else if (mimetype.endsWith("jpeg")) { ImageIO.write(thumb, "jpg" , os); response.setContentType("image/jpeg"); } else { ImageIO.write(thumb, "GIF" , os); response.setContentType("image/gif"); } ServletOutputStream srvos = response.getOutputStream(); response.setContentLength(os.size()); response.setHeader( "Content-Disposition", "inline; filename=\"" + file.getName() + "\"" ); os.writeTo(srvos); srvos.flush(); srvos.close(); } } } // TODO: check and report success } else { PrintWriter writer = response.getWriter(); writer.write("call POST with multipart form data"); } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) * */ @SuppressWarnings("unchecked") @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if (!ServletFileUpload.isMultipartContent(request)) { throw new IllegalArgumentException("Request is not multipart, please 'multipart/form-data' enctype for your form."); } ServletFileUpload uploadHandler = new ServletFileUpload(new DiskFileItemFactory()); PrintWriter writer = response.getWriter(); response.setContentType("text/html;charset=utf-8"); JSONArray json = new JSONArray(); try { List<FileItem> items = uploadHandler.parseRequest(request); for (FileItem item : items) { if (!item.isFormField()) { File file = new File(fileUploadPath, item.getName()); item.write(file); JSONObject jsono = new JSONObject(); jsono.put("name", item.getName()); jsono.put("size", item.getSize()); jsono.put("url", "upload?getfile=" + item.getName()); jsono.put("thumbnail_url", "upload?getthumb=" + item.getName()); jsono.put("delete_url", "upload?delfile=" + item.getName()); jsono.put("delete_type", "GET"); jsono.put("fileid", UUID.randomUUID().toString()); json.put(jsono); } } } catch (FileUploadException e) { throw new RuntimeException(e); } catch (Exception e) { throw new RuntimeException(e); } finally { System.out.println(json.toString()); writer.write(json.toString()); writer.close(); } } private String getMimeType(File file) { String mimetype = ""; if (file.exists()) { // URLConnection uc = new URL("file://" + file.getAbsolutePath()).openConnection(); // String mimetype = uc.getContentType(); // MimetypesFIleTypeMap gives PNG as application/octet-stream, but it seems so does URLConnection // have to make dirty workaround if (getSuffix(file.getName()).equalsIgnoreCase("png")) { mimetype = "image/png"; } else { javax.activation.MimetypesFileTypeMap mtMap = new javax.activation.MimetypesFileTypeMap(); mimetype = mtMap.getContentType(file); } } System.out.println("mimetype: " + mimetype); return mimetype; } private String getSuffix(String filename) { String suffix = ""; int pos = filename.lastIndexOf('.'); if (pos > 0 && pos < filename.length() - 1) { suffix = filename.substring(pos + 1); } System.out.println("suffix: " + suffix); return suffix; } }
相关推荐
简单 jQuery 下拉菜单是入门级的解决方案,适用于那些只需要基本功能的项目。它可能不包含太多复杂的动画效果,但足够满足日常的需求。 **1.18 Styling Drop Down Boxes with jQuery** 这部分内容可能讨论了如何...
11. jQuery File Upload:基于HTML5的Ajax文件上传插件,提供了基础的上传功能和丰富的示例。 12. DataTables:类似Fuel UX的DataGrid,支持排序、分页和搜索等高级功能。 13. Bootsnipp:这是一个代码片段库,...
file_queue_limit : 2, 上传队列数量限制,该项通常不需设置,会根据file_upload_limit自动赋值 flash_url : "http://www.swfupload.org/swfupload_f9.swf", Flash控件的URL flash_width : "1px", flash_...
此外,对于对ThinkPHP感兴趣的读者,文中还推荐了多个与ThinkPHP相关的教程和专题,如《ThinkPHP入门教程》、《ThinkPHP常用方法总结》、《smarty模板入门基础教程》和《PHP模板技术总结》等,这些资源能够帮助...
前端使用Ajax实现异步文件上传,这需要jQuery库或者原生JavaScript的XMLHttpRequest。通过创建FormData对象,将文件添加到其中,然后向后端发送POST请求。记得设置Content-Type为"multipart/form-data"。 ```...
2. **进度条显示**:通过JavaScript或jQuery插件,可以实现在客户端显示上传进度。 3. **分块上传**:对于大文件,jspsmartupload支持分块上传,提高上传效率。 4. **预览功能**:允许用户在上传前预览图片或其他...
开发者可能使用了PHP的内置函数和类库来实现这些功能,如file_upload用于图片上传,以及mysqli扩展进行数据库操作。 【HTML5】作为网页的结构标记语言,HTML5用于创建页面布局和内容展示。在这个项目中,HTML5的新...
许多前端框架和库如jQuery、React、Vue等都有成熟的文件上传组件,如`axios`、`react-dropzone`、`vue-file-upload`等,它们简化了处理复杂上传逻辑的难度。 总之,前端文件上传是一个涉及HTML、CSS、JavaScript...
在开发Web应用时,我们经常需要...对于想要深入学习ThinkPHP框架的开发者,可以查阅相关的教程和文档,如《ThinkPHP入门教程》、《ThinkPHP模板操作技巧总结》、《ThinkPHP常用方法总结》等,以提升自己的开发技能。
阅读本章节请先阅读:xhEditor入门基础,若你已经熟悉xhEditor的基本使用,请往下继续。 xhEditor提供两种方式初始化编辑器: 方法1:利用class属性来初始化和传递各种初始化参数,例: class="xheditor {skin:'...