Dropzone插件的使用(从前台到后台完整流程)

Dropzone插件的使用(从前台到后台完整流程)

leo 1058 2021-04-10

Dropzone插件的使用

1. 下载Dropzone

官网

2. 引入jQuery和Dropzone所需JS

<!-- jQuery 3 -->
<script src="../static/jquery/dist/jquery.min.js"></script>
<!-- Dropzone -->
<script src="../static/plugins/dropzone/min/dropzone.min.js"></script>

为了美观,也把引入CSS引入

<!-- Dropzone -->
<link rel="stylesheet" href="../static/plugins/dropzone/basic.css"/>
<link rel="stylesheet" href="../static/plugins/dropzone/dropzone.css"/>

3.在前端JS代码中初始化Dropzone对象

下面是我已经封装了的方法,可以重复使用。(单独一个JS文件中,需要使用时引入)

//App函数对象
var App = function () {
    //默认的Dropzone参数
    var defaultDropzoneOpts = {
        url: "", // 文件提交地址
        method: "post",  // 也可用put
        paramName: "dropFile", // 提交的参数,默认为file
        maxFiles: 1,// 一次性上传的文件数量上限
        maxFilesize: 2, // 文件大小,单位:MB
        acceptedFiles: ".jpg,.gif,.png,.jpeg", // 上传的类型
        addRemoveLinks: true,
        parallelUploads: 1,// 一次上传的文件数量
        dictDefaultMessage: '拖动文件至此或者点击上传',
        dictMaxFilesExceeded: "您最多只能上传"+this.maxFiles+"个文件!",
        dictResponseError: '文件上传失败!',
        dictInvalidFileType: "文件类型只能是*.jpg,*.gif,*.png,*.jpeg",
        dictFallbackMessage: "浏览器不受支持",
        dictFileTooBig: "文件过大上传文件最大支持.",
        dictRemoveLinks: "删除",
        dictCancelUpload: "取消"
    };
    /*
    * 初始化Dropzone
    * */
    var handlerInitDropzone = function (opts) {
        //关闭Dropzone自动发现功能
        Dropzone.autoDiscover = false;
        //继承
        $.extend(defaultDropzoneOpts,opts);
        return new Dropzone(defaultDropzoneOpts.id, defaultDropzoneOpts);
    };
    return{
        //初始化Dropzone
        initDropzone:function (opts) {
            return handlerInitDropzone(opts);
        }
    }
}();

我们需要在页面合适位置定义一个DIV。class属性设置为:dropzone

<div id="dropz" class="dropzone"></div>

然后调用前面定义好的JS方法来初始化Dropzone。

//初始化Dropzone
var dropz = App.initDropzone({
    id: "#dropz",
    url: "/app/upload",
    init: function () {
        this.on("success", function (file, data) {
            //获取后台传回的文件名,放入输入框
            $("#logowebpath").val(data.fileName);
        });
    }
});

注意:上面的id需要和前面定义<div>的id一致。url就是服务器端的处理地址。
至此,前端基本搞定,后端需要接收文件并返回文件名。

4.后端接收文件并返回文件名

Controller:

@Controller
@RequestMapping("app")
public class UploadController {
    //图片上传路径
    private static final String UPLOAD_PATH = "/static/upload/";

    /**
     * 上传图片
     * @param dropFile
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "upload", method = RequestMethod.POST)
    public Map<String,Object> upload(MultipartFile dropFile, HttpServletRequest request){
        Map<String,Object> result = new HashMap<>();
        //前端上传的文件
        MultipartFile myFile = dropFile;
        //文件名
        String fileName = myFile.getOriginalFilename();
        //后缀
        String fileSuffix = fileName.substring(fileName.lastIndexOf("."));
        //文件上传路径
        String filePath = request.getSession().getServletContext().getRealPath(UPLOAD_PATH);
        //判断路径是否存在
        File file = new File(filePath);
        //不存在 则创建
        if (!file.exists()){
            file.mkdir();
        }
        //将文件更名后写入指定路径下
        file = new File(filePath, UUID.randomUUID() + "" + (System.currentTimeMillis()%10000) + fileSuffix);
        try {
            myFile.transferTo(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //Dropzone上传
        //String serverPath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();
        result.put("fileName",UPLOAD_PATH + file.getName());
        return result;
    }
}

方法上加了@ResponseBody注解,表明返回的是JSON格式数据。我在Maven依赖里添加了Jackson的包,所以Spring可以帮我们将对象转JSON字符串。

需要注意的是:方法的参数名是在Dropzone初始化的指定的。如果想让Spring自动匹配,必须保持一致,不然需要加注解指定。

依赖如下:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.5</version>
</dependency>

另外:需要在SpringMVC的配置文件中配置对媒体类型的解析器:

<!-- 上传文件,设置最大上传文件大小 10M = 10*1024*1024(B) = 10485760 bytes -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="10485760"/>
    <property name="maxInMemorySize" value="4096" />
    <property name="defaultEncoding" value="UTF-8"/>
</bean>

还有,由于使用的不是SpringMVC自带的解析器,所以还需引入如下依赖:

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.2</version>
</dependency>

效果

初始状态:
初始效果
点击或拖拽一张图片到蓝色区域:
点击或拖拽一张图片到蓝色区域

显示服务器端已经存在的图片(如上面上传的)

//创建模拟文件
var mockFile = {
    name: "${appInfo.logowebpath}" , //显示的文件名
    accepted:true
};
dropz.emit("addedfile", mockFile);
//图片地址
var imageUrl = "http://localhost:8080/static/upload/46190493-29ae-4dff-8b82-0cc228841b762561.jpg";
//生成缩略图
dropz.emit("thumbnail", mockFile,imageUrl);
//完成(如果没有,缩略图上会有一根进度条一直存在)
dropz.emit("complete", mockFile);

dropz为初始化时保存的Dropzone对象。

但是上面的方法在显示一张大图片时会只显示左上角的一小部分,本人尚未解决,如有解决方案麻烦评论一下。