zoukankan      html  css  js  c++  java
  • springboot 文件上传示例(webuploader插件)

    1.情景展示

    文件上传,在开发过程中,经常会用到,springboot如何接收上传文件?

    本文将以springboot为例,如何接收前端的文件请求;

    上传文件使用插件更方便,这里我使用webuploader。

    2.前端代码

    第一步:准备webuploader插件放到项目当中;

    由于,springboot在项目启动的时候,会自动将static目录下的静态资源(前端代码)加载到项目当中;

    所以,我这里为了省事儿,就不创建web目录了;

    而且springboot还会自动将resources/static目录下的index.html当做项目的欢迎页(我这里为了省事,就没有配置请求与页面想对照的映射关系)。

    现在,我们来对前端代码进行整体认知;

    一个要存放插件的位置:webuploader;

    一个要展示插件的页面:index.html;

    一个要处理文件上传的js:upload.js;

    index.html需要引入:

    webuploader.css和webuploader.js;

    必须在webuploader.js引入之前引入jQuery.js(因为它依赖jQuery);

    include.js包含的内容如下:

    // 获取请求路径
    var pathName = window.document.location.pathname;
    // 通过截取得到项目名称
    var baseUrl = pathName.substring(0, pathName.substr(1).indexOf('/') + 1);

    用途:获取该项目的名称。

    html的核心代码为:

    <div id="filePicker" style="line-height:15px;" class="webuploader-container">
        <div class="webuploader-pick">选择文件</div>
    </div>

    webuploader插件会通过init()方法,对filePicker这个div里面追加内容,例如:

    js核心代码:

    查看代码
    /**
     * 该插件批量上传的本质:
     * 每个文件单独发送一个上传请求,所以,其本质还是单文件上传,而不是真正含义上的:一次请求包含多个文件。
     */
    this.init = function () {
        var  state = 'pending';
        var upUrl = baseUrl + '/file/upload.do';
        var uploader = WebUploader.create({
            auto: true, // 选择文件后自动上传,默认不自动上传需要触发
            swf: baseUrl + '/webuploader/Uploader.swf', // swf文件路径
            server: upUrl, // 上传文件的接口(替换成你们后端给的接口路径) 
            // 选择文件的按钮。可选。
            // 内部根据当前运行是创建,可能是input元素,也可能是flash.
            pick: '#filePicker',
            accept: {
                extensions: 'xls,xlsx', // 允许的文件后缀,不带点,多个用逗号分割,这里支持老版的Excel和新版的
                mimeTypes: 'application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
            },
            resize: false, // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
           /*  duplicate :true */ //可重复上传
        });
    
        /**
         * 文件被加入队列之前触发
         * @explain 主要用来传其它参数
         */
        uploader.on('beforeFileQueued', function (file) {
            var obj = new Object();
            obj.THEMEID = $('#THEMEID').val();
            uploader.options.formData = obj;
        });
    
        /**
         * 上传成功
         */
        uploader.on('uploadSuccess', function( file, result) {
            alert(JSON.stringify(result));
        });
    
        /**
         * 上传失败
         */
        uploader.on('uploadError', function( file, result) {
            // alert('文件上传失败!');
            alert(JSON.stringify(result));
        });
    
        /**
         * 上传完成
         */
        uploader.on( 'uploadComplete', function( file ) {
            
        });
    
        uploader.on( 'all', function( type ) {
            if ( type === 'startUpload' ) {
                state = 'uploading';
            } else if ( type === 'stopUpload' ) {
                state = 'paused';
            } else if ( type === 'uploadFinished' ) {
                state = 'done';
            }
        });
    }

    HTML完整代码:

    查看代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>文件上传</title>
        <link rel="stylesheet" type="text/css" href="webuploader/webuploader.css">
        <script type="text/javascript" src="common/js/jquery-3.6.0.min.js"></script>
        <script type="text/javascript" src="webuploader/webuploader.js"></script>
        <script type="text/javascript" src="common/js/include.js"></script>
        <script type="text/javascript" src="upload.js"></script>
    </head>
    <body>
        <h1>欢迎来到Marydon的博客园</h1>
        <table border="0" cellpadding="0" cellspacing="0" style=" 100%; height: 90%">
            <tr>
                <td style="text-align: center">
                    <div id="filePicker" style="line-height:15px;" class="webuploader-container">
                        <div class="webuploader-pick">选择文件</div>
                    </div>
                </td>
                <td>
                    <span style="color: #898989">备注:扫描文件格式为xls</span>
                </td>
            </tr>
        </table>
    </body>
    </html>

    注意:关键点在于,引入文件的路径问题,不要搞错了。 

    JAVASCRIPT完整代码:

    查看代码
    var upload = new Upload();
    window.onload = function(){
    	// 不要忘了调用WebUploader的初始化函数
    	upload.init();
    }
    
    function Upload() {
        var object = this;
    
    	/**
    	 * 该插件批量上传的本质:
    	 * 每个文件单独发送一个上传请求,所以,其本质还是单文件上传,而不是真正含义上的:一次请求包含多个文件。
    	 */
    	this.init = function () {
        	var uploadUrl = baseUrl + '/file/upload.do';
    	    var uploader = WebUploader.create({
    	        auto: true, // 选择文件后自动上传,默认不自动上传需要触发
    	        swf: baseUrl + '/webuploader/Uploader.swf', // swf文件路径
    	        server: uploadUrl, // 上传文件的接口(替换成你们后端给的接口路径) 
    	        // 选择文件的按钮。可选。
    	        // 内部根据当前运行是创建,可能是input元素,也可能是flash.
    	        pick: '#filePicker',
    	        accept: {
    	            extensions: 'xls,xlsx', // 允许的文件后缀,不带点,多个用逗号分割,这里支持老版的Excel和新版的
    	            mimeTypes: 'application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    	        },
    	        resize: false, // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
    	       /*  duplicate :true */ //可重复上传
    	    });
    
    		/**
    		 * 文件被加入队列之前触发
    		 * @description 主要用来传其它参数
    		 * @explain 我没有在这里演示,没有传其它参数
    		 */
    		uploader.on('beforeFileQueued', function (file) {
    	        var obj = new Object();
    	        obj.THEMEID = $('#THEMEID').val();
    			uploader.options.formData = obj;
    		});
    
    		/**
    		 * 上传成功
    		 */
    		uploader.on('uploadSuccess', function( file, result) {
    			alert(JSON.stringify(result));
    		});
    
    		/**
    		 * 上传失败
    		 */
    		uploader.on('uploadError', function( file, result) {
    			// alert('文件上传失败!');
    			alert(JSON.stringify(result));
    		});
    
    	};
    }

    注意:关键点在于,需要对插件WebUploader进行初始化。

    3.后端代码

    难点在于:如何接收前端发过来的请求?

    其实,很简单:参数file的值就是MultipartFile类型的文件。

    文件上传,上传的参数至少会有以下6个参数:

    为了方便对于参数的使用,我用实体类来接收这些参数,这样,在后续用到的时候就会很方便。

    查看代码
    import lombok.Getter;
    import lombok.Setter;
    import org.springframework.web.multipart.MultipartFile;
    
    import javax.validation.constraints.NotBlank;
    import javax.validation.constraints.NotNull;
    
    /**
     * 文件上传请求参数
     * @description:
     * @author: Marydon
     * @date: 2022-01-10 15:38
     * @version: 1.0
     * @email: marydon20170307@163.com
     */
    @Getter
    @Setter
    public class UploadParamsDto {
        @NotBlank(message = "id:不能为空")
        private String id;
        @NotBlank(message = "name:不能为空")
        private String name;
        @NotBlank(message = "type:不能为空")
        private String type;
        @NotBlank(message = "lastModifiedDate:不能为空")
        private String lastModifiedDate;
        @NotBlank(message = "size:不能为空")
        private String size;
        @NotNull(message = "file:不能为空")
        private MultipartFile file;
    }

    如果不需要对参数进行非空校验,删掉这些属性对应的注解即可。

    JAVA控制层完成代码:

    查看代码
    import com.example.upload.web.dto.UploadParamsDto;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.validation.annotation.Validated;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * 文件上传控制层
     * @description:
     * @author: Marydon
     * @date: 2022-01-10 10:16
     * @version: 1.0
     * @email: marydon20170307@163.com
     */
    @Slf4j
    @RestController
    @RequestMapping("/file")
    public class UploadController {
        // 文件存放路径:项目路径/files
        private static final String UPLOADED_FOLDER = System.getProperty("user.dir") + File.separator + "files";
    
        /*
         * 文件上传
         * @attention: 不支持批量上传
         * @description: 请求类型-multipart/form-data
         * @date: 2022/1/11 10:23
         * @param: paramsDto
         * @return: java.util.Map
         */
        @PostMapping("/upload.do")
        public Map<String, Object> upload(@Validated UploadParamsDto paramsDto) {
            // 即将返回的数据
            Map<String, Object> resultMap = new HashMap<>(2);
            resultMap.put("isSuccess", true);
            resultMap.put("error", "");
    
            Map<String, String> errorMap = new HashMap<>();
            // 获取上传的文件
            MultipartFile file = paramsDto.getFile();
            // 新文件的文件名
            String fileName = System.currentTimeMillis() + "_" + paramsDto.getName();
            // 新文件的生成
            File copyFile = new File(UPLOADED_FOLDER + File.separator + fileName);
            // 目录不存在就自动创建
            copyFile.mkdirs();
            try {
                // 将multipartfile文件转移到file对象所代表的文件中
                // 该方法可以将文件夹直接变为文件
                // 当copyFile代表的是一个目录时,正常情况文件是无法输入的,而transferTo()方法会将该目录直接变为文件并输入数据
                file.transferTo(copyFile);
            } catch (IOException e) {
                e.printStackTrace();
                log.error(e.getMessage());
                // 如果报错,意味着该文件上传失败,将原文件名和报错信息返回
                errorMap.put(paramsDto.getName(), e.getMessage());
            }
    
            if (!errorMap.isEmpty()) {
                resultMap.put("error", errorMap);
            }
    
            return resultMap;
        }
    }

    难点还有:如何获取保存文件的目录;

    新文件名的命名规则;

    文件的快速复制。

    当然,如果只是根据上传的文件进行解析处理,而不保存的话,不会遇到以上3个问题。

    说明:

    请求格式:multipart/form-data;

    返回格式:application/json。

    另外,如果,需要对实体类UploadParamsDto进行参数校验,除了需要在它前面加注解@Validated外,还要引入对应的注解jar依赖。

    <!--spring对参数进行校验:hibernate validator-->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>6.0.18.Final</version>
    </dependency>

    更多细节,我在之前的文章讲过。 

    4.效果展示

    直接来到欢迎页

    点击“选择文件”,选择要上传的文件,支持多选。

    最终上传的文件存放位置

    5.扩展

    如果,对上传文件的大小有限制的话,可以通过配置来实现。

    查看代码
    
    ####spring配置####
    ####开发环境数据源配置
    spring:
      ###文件上传大小限制
      servlet:
        multipart:
          #是否支持批量上传(默认值 true)
          enabled: true
          #上传文件最大为 1M(默认值 1M)
          max-file-size: 10MB
          #上传请求最大为 10M(默认值 10M)
          max-request-size: 10MB
          #文件大小阈值,当大于这个阈值时将写入到磁盘,否则存在内存中(默认值0,即:直接将文件写入磁盘)
          file-size-threshold: 0
          #判断是否要延迟解析文件(默认值false)
          resolve-lazily: false
          #存放上传文件的临时目录
          location:

    写在最后

      哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

     相关推荐:

    本文来自博客园,作者:Marydon,转载请注明原文链接:https://www.cnblogs.com/Marydon20170307/p/15794176.html

  • 相关阅读:
    Docker Compose实例
    Jenkins远程执行shell出现java: command not found
    SpringBoot之导入导出Excel
    在Jenkins中配置执行远程shell命令
    XJar: Spring-Boot JAR 包加/解密工具,避免源码泄露以及反编译
    Elasticsearch集成ik分词器
    AAAAAA
    Logstash-安装logstash-filter-multiline插件(解决logstash匹配多行日志)
    Elastic Kibana文档
    failed to create rwlayer: lstat /var/lib/docker/overlay2/ no such file or directory
  • 原文地址:https://www.cnblogs.com/Marydon20170307/p/15794176.html
Copyright © 2011-2022 走看看