小编通过研究dropzone进行上传文件已有两周了,之前我也是在网上找dropzone教程学习,却发现,尼玛。。。他们那是教程么???直接把官网的翻译过来搞几个代码显示一下就是教程了???天啊,搞得我真想说:“我,f f f f f 佛慈悲”,当然啦,有几个教程还是挺细的,但是看他实现了,但是我们想实现他的那种效果,却没门路,,,因为他们不提供dropzone版本下载,不知道他们用的是哪个版本。好咯。费了很久功夫我终于拿到想要的资源了,而且把后台代码也实现了,要明白,他这个插件是不提供上传的后台代码的,这个代码需要自己编写。不过上传代码网上也能找到,都是大同小异。但是,我希望大伙还是看看官方文档比较好,这样可以对该插件了解得更详细。

官方文档(英文版):https://www.dropzonejs.com/#event-sending

官方文档(中文版):http://wxb.github.io/dropzonejs.com.zh-CN/dropzonezh-CN/#installation

如果看完该教程遇到有小问题可以查看官方文档

项目源码(download)

先看效果

ok,效果图已经出来了。大伙们,看到如此美丽的画面,动心没有啊??

看完效果,有兴趣的同学可以继续往下看,我给你讲解实现的过程以及需要注意的事项。

要说逻辑其实也不难,新建一个form表单,表单有action处理页面,action页面就是处理上传的页面,这个dropzone插件的任务就是帮你对上传的文件进行列队上传,就像管理员:你们这群孩子,领奖状就要排好队,一次上n个(默认是2个,可配置)来领奖,后面的同学排好队,等待领奖。并且监听每一个文件的上传状态。接下来上代码:

index.jsp(注意,此form需要添加class="dropzone",因为这个是dropzone.css给dropzone类定义的样式)

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>dropzone上传插件测试</title><!-- jquery -->
<script type="text/javascript" src="${pageContext.request.contextPath }/static/js/jquery-3.3.1.min.js"></script><!-- 注意:引入dropzone的js和css文件最好放在同一个目录,不然的话,会出现各种错误 -->
<script type="text/javascript" src="${pageContext.request.contextPath }/static/dropzone/dropzone.js"></script>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath }/static/dropzone/dropzone.css" ><style type="text/css">
#uploadForm {min-height: 200px;width: 800px;margin-right: -810px;margin-bottom: 30px;display: inline-block;background-color:white;
}
#uploadForm #uploadBtn {position: absolute;top: 2px;right: -294px;font-family: "方正舒体";font-size: 40px;width: 276px;height: 80px;cursor: pointer;
}
</style><script type="text/javascript">
/* Dropzone上传插件配置 */  var IsServerError = false;//服务器获取配置出错
var fileList = new Array();
var fileList_Uploading = new Array();
var uploaded_filePaths = new Array();//已上传的文件在服务器的路径集合;用于遇到异常时删除已上传的文件。(相当于回滚)
var arr_file = new Array();
var arr_xhr = new Array();
Dropzone.options.uploadForm = { //此处的"uploadForm" 是dropzone的HTML元素ID的驼峰命名,比如<form id="my-form"></form>,那么此处应该写:Dropzone.options.myFormparamName: "MyFile", //上传字段名 filedNamemaxFiles: 100, //最大上传数量maxFilesize:1000, // MB 单个文件大小上限filesizeBase:1000,acceptedFiles: ".doc,.docx,.xls,.xlsx,.ppt,.pptx,.zip,.rar,.7z,.txt,image/*,application/pdf,.psd",addRemoveLinks: true,clickable: true,autoProcessQueue: true, // true:自动上传,一次性上传parallelUploads个文件,上传成功后后面排队的其他队伍也会继续排队上传。false:关闭自动上传, 手动调度 ,但每次需要点击“上传”按钮才会触发上传,排队的其他文件不会自动上传。 parallelUploads: 2, //最大并行处理量(一次同时上传的个数,不设置的话,默认:2个)/* 插件消息翻译 *//*  dictDefaultMessage: '<i class="fa fa-cloud-upload"></i>拖拉文件上传<br />或 <i class="fa fa-thumbs-down"></i>点此上传', */dictInvalidFileType: '仅支持以下格式文件:.doc,.docx,.xls,.xlsx,.ppt,.pptx,.zip,.rar,.7z,.txt,image/*,application/pdf,.psd',dictFileTooBig: '文件超出最大10M约束',dictMaxFilesExceeded: '超出最大上传数量',dictCancelUpload: '取消上传',dictRemoveFile: '删除',dictCancelUploadConfirmation: '确认取消上传',dictResponseError:"文件上传失败!",dictDefaultMessage:"<span class='bigger-150 bolder'><i class='icon-caret-right red'></i>拖动文件</span>上传\ <span class='smaller-80 gre'>(或者点击上传)</span> <br /> \ <i class='upload-icon icon-cloud-upload blue icon-3x'></i>",/* 上传缩略图预览模板 */previewTemplate: ' <div id="viewer"  class="dz-preview dz-file-preview">    <div class="dz-details" onClick="viewFile(this)" name="">  <div style="display:none;" class="fileId"></div>   <div class="dz-filename"><span data-dz-name></span></div>       <div class="dz-size" data-dz-size></div>    <img data-dz-thumbnail />    </div>    <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>   <div class="dz-success-mark"><span>?</span></div>                           <div class="dz-error-mark"><span>?</span></div>                             <div class="dz-error-message"><span data-dz-errormessage>""</span></div>                          </div>                       ',/*accept: function(file, done) {fileList_Accepted.push(file)done();}, */init: function(){ /*  var self = this; // 非自动上传。点击上传按钮开始ajax上传 this.element.querySelector("button#uploadBtn").addEventListener("click", function(e) {e.preventDefault();e.stopPropagation();self.processQueue(); }); *//*var accept = this.getAcceptedFiles();//所有接受的文件(合法)var reject = this.getRejectedFiles();//所有拒绝的文件(非法)var uploading = this.getQueuedFiles();//所有上传中的文件var queued = this.getRejectedFiles(); //所有排队中的文件*/       var this_ = this;fileList = this.getAcceptedFiles();//所有接受的文件(合法)this.on("addedfile", function(file) {  //新添加的文件,每添加一个新文件都会触发一次该函数,可以使用alert测试一下//alert("addedfile:"+file.name)  //fileList.push(file); }) this.on("canceled", function(file,response) {  //当取消文件上传式调用//单个文件点击“取消上传”并确认后执行该函数,将该文件从上传列队中移除。for(var i in arr_file){if(arr_file[i].name.trim()==file.name.trim()){var xhr = arr_xhr[i]; xhr.abort();}}}) this.on("sending", function(file,xhr,formData) {  //文件上传前调用 arr_file.push(file);arr_xhr.push(xhr); }) this.on("uploadprogress", function(file,progress,bytesSent) {  //文件上传监听器(file:文件、progress:上传进度n%、bytesSent:)})   this.on("complete", function(file,response) { //当上传完成,成功或者出现错误时调用.//alert("complete:"+response)})this.on("success", function(file,response) {  //文件已经成功上传,获得服务器返回信息作为第二个参数//每个文件上传成功后有以下处理//1.该文件会自动将UI拼接到上传区域,我们需要将文件的服务器路径隐藏到该UI中。为移除等操作提供便利。IsServerError =  JSON.parse(JSON.parse(response).error)  var File_PhysicalPath = "";var list = JSON.parse(JSON.parse(response).list_client)   for(var k in list){var file0 = list[k]; //alert(file0.fileName.trim()+":"+file.name+"\n"+file0.fileSize+":"+file.size)if(file0.fileName.trim()==file.name&&file0.fileSize==file.size){File_PhysicalPath = file0.physical_path;}}  $(".dz-filename span").each(function(){if($(this).text().trim()==file.name.trim()){  $(this).parent().parent().find(".fileId").text(File_PhysicalPath); uploaded_filePaths.push(File_PhysicalPath);}}) }); this.on("queuecomplete", function(file,response) { //当上传队列中的所有文件上传完成时调用.//alert("任务完成!") if(IsServerError){alert("服务器获取文件夹配置失败!即将回滚上传操作");//若提示该警告,请查看com.nbc.demok.io.Upload.multi_upload()方法中的PropertiesUtils.getProperty("")获取配置是否为空。为空的话,请及时在配置文件中添加该配置//1.后台:遇到服务器异常,删除已上传的服务器上的文件 var filePaths = "";for(var i in uploaded_filePaths){var path = uploaded_filePaths[i]; if(path!=""){filePaths = (filePaths=="")?path:(filePaths+"¤¤¤¤¤"+path);}} if(filePaths.trim()!=""){removeFiles_From_Server(filePaths);//服务器:移除所有未遇到错误之前的刚刚上传了的文件} //2.前端:移除所有显示的附件this.removeAllFiles(true);  }});this.on("removedfile", function(file) { //删除单一文件 //alert("removedfile:"+file.name+"\npath:"+$(file.previewElement).find(".fileId").text()) //文件在服务器上的路径var filePath = $(file.previewElement).find(".fileId").text().trim();//删除文件操作有以下步骤://1.使用ajax删除在服务器上的该文件if(filePath!=""){ removeFiles_From_Server(filePath);} //2.删除文件在前端的显示this.removeFile(file); });this.on("error", function(file, errorMessage){ //不接受该文件(非定义的可接受类型)或上传失败//alert("error:"+file.name+"    "+errorMessage+"\nIsServerError:"+IsServerError)//this.removeFile(file); });}
};function removeFiles_From_Server(filePaths){ var path = $("#basePath").val();if(path==undefined){alert("获取工程根目录出错");//请查看页面是否有id="basePath"的输入框,并且该输入框存放项目根目录return;} $.ajax({type:"POST",timeout: 60000,dataType:"json", url:path+"/backend/upload.jsp?method=remove",  //后台url请求,处理传递的参数async: false,data:{ filePaths:escape(escape(filePaths))},beforeSend: function (xhr) {$("#loading_").css("display","block");    // 数据加载成功之前,使用loading组件(使用加载中的图片,显示图片gif即可) },success:function(data){//ajax请求成功执行该函数$("#loading_").css("display","none");     //关闭加载中图片  //alert("删除成功,数量:"+data.count+"个")},error: function(XMLHttpRequest, textStatus, errorThrown) {$("#loading_").css("display","none") // if(textStatus=="timeout"){ alert(" 请求超时,可能是网络较慢,请重新加载") }else{alert("XMLHttpRequest.status:"+XMLHttpRequest.status+"\n"+"XMLHttpRequest.readyState:"+XMLHttpRequest.readyState+"\n"+"textStatus:"+textStatus);    }}});
}function viewFile(obj){ var filePath = $(obj).find(".fileId").text();  if(filePath.trim().length>0){p = filePath.split(".");var suffix = "."+p[p.length-1];   //后缀为 [.doc .docx .xls .xlsx .ppt .pptx]可以转pdf在线浏览//alert(suffix);var IsOffice = false;var arr = new Array(".doc",".docx",".xls",".xlsx",".ppt",".pptx")for(var i in arr){if(suffix==arr[i].trim()){IsOffice = true;}} if(IsOffice){Open_Office_File(filePath)}else{Open_Not_Office_File(filePath);} }
}function Open_Office_File(path){alert("查看文件处理:"+path)
}function Open_Office_File(path){alert("查看文件处理:"+path)
}</script></head>
<body>   <!--  工程根目录 --><input type="hidden" id="basePath" value="<%=request.getContextPath()%>"/><br><form id="uploadForm" action="backend/upload.jsp" class="dropzone"> <!-- <button id="uploadBtn" class="btn btn-success"> 确 认 上 传 </button> --></form></body>
</html>

上面的代码是图一效果图。

然后激活dropzone的脚本也有了,配置也有注释了,我就挑几个再讲讲吧

addRemoveLinks:true//每个文件添加“删除”链接

acceptedFiles:定义的是可接受文件类型,也就是在选择文件时帮你筛选以上类型的文件出来给你选。

parallelUploads:最大并行处理量,也就是上面提到的,一次上来n个孩子上台领奖,这个n是多少,就是在此处配置。

autoProcessQueue:默认是true,为true代表文件拖放到上传域或选择文件之后马上帮你上传,相当于自动上传。如果设置为false的话,那选择文件后不会进行上传,只是单纯的把文件列出来,当点击“上传”按钮才会触发上传,这个按钮需要绑定click事件来触发上传,也就是我上面的init函数注释掉的,那个就是用来进行手动触发上传的。但手动触发上传存在一个大大的问题,就是点击一次帮你上传parallelUploads个文件,后面排队的文件不会继续上传,需要再点击一次上传,那排队中的下两个才会触发上传,因此,要么你设置该参数为true(自动上传),要么你设置为false(手动上传)并且将parallelUploads设置得大一点(如:100)。这样,上传者才会好受一点。个人觉得还是用自动上传最好。

previewTemplate:每一个文件的html模板,如上图图二,不管上传成功 / 上传中 / 等待上传的文件都使用这个html模板进行拼接。注意:是以这个html作为模板进行拼接,显示。

事件:

addedfile:每拖放/选择一个文件进来都会执行一次该函数

canceled:取消上传该文件。取消后会自动调用removedfile事件

uploadprogress:文件上传中的处理,dropzone原本已经做好了进度条控制,你要自定义进度条的话,在这里进行自定义配置

success:每一个文件上传成功都会触发该函数。

queuecomplete:当所有文件处理完成执行该函数

removedfile:移除该文件(注意:dropzone仅将前端的UI删除,并不会真正删除你服务器上面的文件,因此,需要在该函数添加一个ajax事件进行删除服务器上的该文件。删除文件,那就需要文件所在路径,那,我怎么知道这个文件的路径?哈哈,所以我在html模板添加了一个div用来存放这个服务器文件的路径,我说了,每上传成功一个文件就会触发一次success事件,我们就在这个事件里面将上传成功的文件路径放到html模板中,然后系统会自动拼接这个html模板到上传域中,你说,我是不是很聪明。哈哈)

error:文件不在可接受文件类型范围内 / 上传失败 时触发该函数。

二:后台代码


import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.json.JSONException;
import org.json.JSONObject;
import com.google.gson.Gson;
import upload.model.UploadResult;public class Upload {public static String  basePath = "D:/WebSite/KMS";
public static String  baseFoder = "Test";/** @version 1.0* @author Demonor* @Class IsUsing = true* */public static void multi_upload(String UID,HttpSession session,HttpServletRequest request,HttpServletResponse response) throws IOException, JSONException{boolean error = false;String physical_path = "";String server_path = "";UploadResult result =  new UploadResult();List<UploadResult> list_client = new ArrayList<UploadResult>();List<UploadResult> list_server = new ArrayList<UploadResult>();Gson gson = new Gson(); JSONObject json = new JSONObject();FileItemFactory factory = new DiskFileItemFactory();   ServletFileUpload upload = new ServletFileUpload(factory);  SimpleDateFormat fmt = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS");String date = fmt.format(System.currentTimeMillis()); error = (baseFoder.equals(""))?true:false; String upload_foder = basePath+"/"+baseFoder;error = (upload_foder.equals(""))?true:false;System.out.println("error:"+error);if(!error) { upload.setHeaderEncoding("UTF-8");  try{List items = upload.parseRequest(request);  Iterator iter = items.iterator();   while (iter.hasNext()) {  FileItem item = (FileItem) iter.next();  if (item.isFormField()) {  String name = item.getFieldName();  String value = item.getString("utf-8"); } else {   String fieldName = item.getFieldName(); String OriginalName = item.getName().substring(item.getName().lastIndexOf("\\")+1);String fileName = OriginalName.substring(0, OriginalName.lastIndexOf("."))+"¤※◎"+String.valueOf(UID)+"_"+date+"¤※◎"+item.getName().substring(item.getName().lastIndexOf("."),item.getName().length());;  String contentType = item.getContentType();   boolean isInMemory = item.isInMemory();  long sizeInBytes = item.getSize();  File f = new File(upload_foder);if(!f.exists()) {f.mkdirs();} server_path = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+"/temp/"+fileName;physical_path = upload_foder+"/"+fileName;File uploadedFile = new File(physical_path);  System.out.println("physical_path:"+physical_path);//System.out.println("fileName:"+fileName);//System.out.println(uploadedFile.length()+"============");item.write(uploadedFile);   list_server.add(new UploadResult(fileName,uploadedFile.length(),physical_path,""));list_client.add(new UploadResult(OriginalName,uploadedFile.length(),physical_path,""));}  }  /* while */  }catch(Exception e){ e.printStackTrace();}}response.setContentType("text/text;charset=utf-8");PrintWriter out = response.getWriter(); json.put("error", error);json.put("list_server", gson.toJson(list_server)); json.put("list_client", gson.toJson(list_client)); out.print(json.toString());  //out.flush();out.close();}public static int removeFile(String[] paths,HttpSession session) {int k = 0;for(String filePath : paths) { boolean b = false;filePath = ScriptDecoder.unescape(ScriptDecoder.unescape(filePath));File file = new File(filePath);if (!file.exists()) {System.out.println("系统找不到指定的路径:" + filePath);}else{b = file.delete();k ++;}}  return k;}}

model:


import java.io.Serializable;public class UploadResult implements Serializable{/*** */private static final long serialVersionUID = 7434128027715196787L;private String fileName;     //文件名称private long fileSize;       //文件大小private String physical_path;//文件上传到服务器的物理路径private String server_path;  //文件上传到服务器的服务器路径,可访问的http://xxx.com/xxx.pngpublic UploadResult() {}public UploadResult(String fileName,long fileSize,String physical_path,String server_path) {this.fileName = fileName;this.fileSize = fileSize;this.physical_path = physical_path;this.server_path = server_path;}public String getFileName() {return fileName;}public void setFileName(String fileName) {this.fileName = fileName;}public long getFileSize() {return fileSize;}public void setFileSize(long fileSize) {this.fileSize = fileSize;}public String getPhysical_path() {return physical_path;}public void setPhysical_path(String physical_path) {this.physical_path = physical_path;}public String getServer_path() {return server_path;}public void setServer_path(String server_path) {this.server_path = server_path;}public static long getSerialversionuid() {return serialVersionUID;} }

dropzone上传插件详细教程,含demo相关推荐

  1. 20+ 个很棒的 jQuery 文件上传插件或教程(此文值得“推荐”和“收藏”)

    文件上传是网站很常见的功能之一,通过使用 jQuery 可以让上传过程更加人性化,更好的用户体验.本文介绍20个jQuery的文件上传插件,其中有一些是教程. 1. Plupload Plupload ...

  2. 阿里云服务器ecs从购买到上传网站详细教程

    最近花了好几天的时间在阿里云ecs上,从最开始的购买ecs就遇到了很多问题,个人觉得这些东西对于新手来说很不友好,现在把我从购买完ecs到搭建网站的过程以及遇到的一些问题写下来,也算是一次总结. 可能 ...

  3. jsp页面文件上传的详细教程

    0)导入文件上传的依赖 <dependency><groupId>commons-fileupload</groupId><artifactId>com ...

  4. php dropzone.js中文教程,JavaScript 文件拖拽上传插件 dropzone.js 介绍

    dropzone.js 是一个开源的 JavaScript 库,提供 AJAX 异步上传功能. 安装 下载dropzone.js文件并添加到页面中即可.Dropzone 不依赖 jQuery 框架. ...

  5. jQuery图片批量上传插件源码,支持批量上传、预览、删除、放大,可配置上传数量、上传大小、追加方式,含详细使用文档

    jQuery图片批量上传插件源码,支持批量上传.预览.删除.放大,可配置上传数量.上传大小.追加方式,含详细使用文档 程序包内含使用Demo 完整程序源代码:jQuery图片批量上传插件源码 上传前 ...

  6. dropzone.js php,超详细版Dropzone.js上传插件的使用实例-适用tp

    其实一直都再找一款上传插件,但是今天遇到了一款相对比较好的插件,干净纯洁. [![](https://cdn.micuer.com/data/upload/20210121/60091f0d95453 ...

  7. JavaScript 文件拖拽上传插件 dropzone.js 介绍

    dropzone.js 是一个开源的 JavaScript 库,提供 AJAX 异步上传功能. 安装 下载dropzone.js文件并添加到页面中即可.Dropzone 不依赖 jQuery 框架. ...

  8. query上传插件uploadify参数详细分析

    query上传插件uploadify参数详细分析 Uploadify Version 3.2 官网:http://www.uploadify.com/ 注:文件包里有两个js分别是:jquery.up ...

  9. jQuery上传插件Uploadify使用Demo、本地上传(ssm框架下)

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 效果: 1. jar包导入: <!-- 文件上传组件 --><dependency ...

最新文章

  1. Javascript Java C++系列
  2. winform 系统托盘程序
  3. GreenPlum查看表和数据库大小
  4. 抓包工具 - Fiddler(详细介绍)
  5. 武侠乂怎么修改服务器,武侠乂怎么操作 按键功能详细介绍
  6. String类常用方法记录
  7. TypeError at / 'AnonymousUser' object is not iterable
  8. Win10 64位安装SQL2000(个人版)
  9. xshell 常用配置_Xshell连接报Connection closed by foreign host错误的解决办法
  10. 获取URL Schema
  11. (转)贝莱德,从零到五万亿
  12. 计算机科学之父--图灵
  13. 天轰穿·甜老丝儿。科创少年
  14. HTML5海报生成器源码,原生js小项目 - canvas海报生成器
  15. 随机抽取一名同学回答问题,7/4更新一次
  16. 什么软件可以测试手长,手相测试扫一扫软件
  17. React `controlled` 及 `uncontrolled` 组件
  18. 水晶报表 (Crystal Reports 2008)的配置
  19. openwrt strongswan IPSec IKEV2
  20. 天勤python_天勤量化

热门文章

  1. Fabric源码分析之九数据库存储源码分析leveldb
  2. 广联达搭建虚拟服务器,广联达软件安装在云服务器上
  3. android初中级面试必备
  4. 阿里Android开发规范:安全与其他
  5. CDN服务商和服务域名
  6. 我们结婚吧,在区块链上!
  7. 索引的几种类型以及索引的优缺点
  8. 学计算机大一新生在暑假的准备
  9. 让你的微信公众平台中支持QQ在线客服功能
  10. html界面出现 section,如何在HTML5中正确使用“ section”标签?