zoukankan      html  css  js  c++  java
  • spring boot:单文件上传/多文件上传/表单中多个文件域上传(spring boot 2.3.2)

    一,表单中有多个文件域时如何实现说明和文件的对应?

         1,说明和文件对应

         文件上传页面中,如果有多个文件域又有多个相对应的文件说明时,

          文件和说明如何对应?

          我们在表单中给对应的file变量和text变量加上相同的数字即可

          在演示项目中使用了一个动态添加文件说明和文件域的页面,

          供大家参考

        2,spring boot的文件上传要注意的地方:

            需要修改spring boot的配置文件,

            指定允许上传的文件大小,

            指定连接的超时时间,避免文件太大时上传超时

           如果接入层使用了nginx,则nginx也要做相应配置

    说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

             对应的源码可以访问这里获取: https://github.com/liuhongdi/

    说明:作者:刘宏缔 邮箱: 371125307@qq.com

    二,演示项目相关信息

    1,项目地址:

    https://github.com/liuhongdi/fileupload

    2,功能说明:

       分别演示了:单文件上传,

                         多文件上传

                         同一个表单中有多个文件域时的上传

    3,项目结构:如图:

    三,配置文件说明

    1,application.properties

    #thymeleaf
    spring.thymeleaf.cache=false
    spring.thymeleaf.encoding=UTF-8
    spring.thymeleaf.mode=HTML
    spring.thymeleaf.prefix=classpath:/templates/
    spring.thymeleaf.suffix=.html
    
    #upload
    spring.servlet.multipart.maxFileSize=10MB
    spring.servlet.multipart.maxRequestSize=30MB
    #tomcat,
    server.tomcat.connection-timeout=20000
    server.tomcat.max-http-form-post-size=30MB
    
    #error
    server.error.include-stacktrace=always
    #errorlog
    logging.level.org.springframework.web=trace

    说明:
    spring.servlet.multipart.maxFileSize=10MB    //单个文件最大的size
    spring.servlet.multipart.maxRequestSize=30MB    //整个表单中上传文件一共最大的size
    #tomcat,
    server.tomcat.connection-timeout=20000           //tomcat的连接超时时间,注意不能太短,我们在这里使用20秒
    server.tomcat.max-http-form-post-size=30MB    //tomcat的表单最大post的文件大小

    四,java文件说明

    1,FileController.java

    @Controller
    @RequestMapping("/file")
    public class FileController {
    
        //文件的保存路径
        private final static String FILE_BASE_PATH = "/data/file/html";
    
        //多文件域上传页面
        @GetMapping("/uploadadd")
        public String uploadAdd(ModelMap modelMap) {
            return "image/uploadadd";
        }
    
        //处理多个文件域的表单上传
        @PostMapping("/uploadadded")
        @ResponseBody
        public RestResult uploadadded(@RequestParam Map<String,String> params,HttpServletRequest request) {
            RestResult res = new RestResult();
            int num =  Integer.parseInt(params.get("num"));
            //打印文件域的名字,供调试用
            Iterator<String> it = ((MultipartHttpServletRequest)request).getFileNames();
            while (it.hasNext()) {
                String uploadFile = it.next();
                System.out.println("filename:"+uploadFile);
            }
    
            //根据表单中文件元素的数量遍历
            for (int i=1;i<=num;i++) {
                //text
                String curText = params.get("text"+i);
                System.out.println("text:"+curText);
                //file
                MultipartFile curFile = ((MultipartHttpServletRequest)request).getFile("file"+i);
                if (curFile.isEmpty()) {
                    continue;
                }
                //System.out.println("text:"+curText);
                String fileName = curFile.getOriginalFilename();
                System.out.println("文件名: " + fileName);
                // 文件后缀
                int lastDot = fileName.lastIndexOf(".");
                lastDot++;
                String fileType = fileName.substring(lastDot);
                // 重新生成唯一文件名,用于存储数据库
                String fileSn = UUID.randomUUID().toString();
                Map<String, String> map2 = new HashMap<String, String>();
                String destFilePath = FILE_BASE_PATH+"/"+fileSn+"."+fileType;
                File dest = new File(destFilePath);
                try {
                    curFile.transferTo(dest);
                } catch (IOException e) {
                    System.out.println("save ioexception");
                    e.printStackTrace();
                }
            }
            return res.success(0,"上传成功");
        }
    
        //单文件/多文件上传页面
        @GetMapping("/upload")
        public String upload(ModelMap modelMap) {
            return "image/upload";
        }
    
        //处理单文件/多文件上传
        @PostMapping("/uploaded")
        @ResponseBody
        public RestResult uploaded(HttpServletRequest request) {
            RestResult res = new RestResult();
            List<MultipartFile> list = ((MultipartHttpServletRequest)request).getFiles("files");
            for (MultipartFile multipartFile : list) {
                if (list.isEmpty()) {
                    continue;
                }
                // 文件名
                String fileName = multipartFile.getOriginalFilename();
                System.out.println("文件名: " + fileName);
                // 文件后缀
                int lastDot = fileName.lastIndexOf(".");
                lastDot++;
                String fileType = fileName.substring(lastDot);
                    // 重新生成唯一文件名,用于存储数据库
                    String fileSn = UUID.randomUUID().toString();
                    Map<String, String> map2 = new HashMap<String, String>();
                    String destFilePath = FILE_BASE_PATH+"/"+fileSn+"."+fileType;
                    File dest = new File(destFilePath);
                    try {
                        multipartFile.transferTo(dest);
                    } catch (IOException e) {
                        System.out.println("save ioexception");
                        e.printStackTrace();
                        return res.error(0,"上传失败");
                    }
            }
            return res.success(0,"上传成功");
        }
    }

    说明:多个文件域上传时,主要是把file变量和text变量做对应

    2,RestResult.java

    //api通用返回数据
    public class RestResult<T> {
    
        //uuid,用作唯一标识符,供序列化和反序列化时检测是否一致
        private static final long serialVersionUID = 7498483649536881777L;
        //标识代码,0表示成功,非0表示出错
        private Integer code;
    
        //提示信息,通常供报错时使用
        private String msg;
    
        //正常返回时返回的数据
        private T data;
    
        //constructor
        public RestResult() {
        }
    
        //constructor
        public RestResult(Integer status, String msg, T data) {
            this.code = status;
            this.msg = msg;
            this.data = data;
        }
    
        //返回成功数据
        public RestResult success(T data) {
            return new RestResult(ResponseCode.SUCCESS.getCode(), ResponseCode.SUCCESS.getMsg(), data);
        }
    
        public static RestResult success(Integer code,String msg) {
            return new RestResult(code, msg, null);
        }
    
        //返回出错数据
        public static RestResult error(ResponseCode code) {
            return new RestResult(code.getCode(), code.getMsg(), null);
        }
    
        public static RestResult error(Integer code,String msg) {
            return new RestResult(code, msg, null);
        }
    
        public Integer getCode() {
            return code;
        }
        public void setCode(Integer code) {
            this.code = code;
        }
    
        public String getMsg() {
            return msg;
        }
        public void setMsg(String msg) {
            this.msg = msg;
        }
    
        public T getData() {
            return data;
        }
        public void setData(T data) {
            this.data = data;
        }
    }

    五,html文件说明

    1,upload.html

    <html lang="en">
    <head>
        <script type="text/javascript" language="JavaScript" src="/js/jquery-1.6.2.min.js"></script>
    </head>
    <body>
    <div style="100%;height:20px;background:#ffffff;font-size: 16px;" ></div>
    <div id="content" style="800px;">
        <div style="800px;float:left;">
           <!--====================main begin=====================-->
            <div style="260px;height:200px;float:left;background: #eeeeee;padding-left: 10px;padding-top: 10px;">
                单文件上传<br/>
                说明:不能多选<br/>
                <input id="fileone" type="file" name="fileone" /><br/><br/>
                <input type="button" name="go" value="单文件上传" onclick="go_single_add()" />
            </div>
            <div style="380px;height:200px;float:left;margin-left:20px;background: #eeeeee;padding-left: 10px;padding-top: 10px;">
                多文件上传<br/>
                说明:可以多选<br/>
                <input id="files" type="file" name="files" multiple /><br/><br/>
                <input type="button" name="go" value="多文件上传" onclick="go_multi_add()" />
            </div>
            <!--====================main   end=====================-->
        </div>
    </div>
    
    <script>
        //单文件上传
        function go_single_add(){
            //把表单中选中的文件添加到postdata
            var postdata=new FormData();
            if ($("#fileone")[0]==null || $("#fileone")[0].files.length<1){
                alert("未选中图片")
                return false
            }
            for (var i=0;i<$("#fileone")[0].files.length;i++){
                postdata.append("files",$("#fileone")[0].files[i])
            }
            $.ajax({
                type:"POST",
                url:"/file/uploaded",
                data:postdata,
                //返回数据的格式
                datatype: "json",//"xml", "html", "script", "json", "jsonp", "text".
                processData: false,
                contentType: false,
                //成功返回之后调用的函数
                success:function(data){
                    if (data.code == 0) {
                        alert('上传成功:'+data.msg);
                        //window.location.href="/image/imagelist";
                    } else {
                        alert("上传失败:"+data.msg);
                    }
                },
                //调用执行后调用的函数
                complete: function(XMLHttpRequest, textStatus){
                },
                //调用出错执行的函数
                error: function(XMLHttpRequest, textStatus, errorThrown){
                    alert(XMLHttpRequest.readyState + XMLHttpRequest.status + XMLHttpRequest.responseText);
                }
            });
        }
        //多文件上传
        function go_multi_add(){
            //把表单中选中的文件添加到postdata
            var postdata=new FormData();
            if ($("#files")[0]==null || $("#files")[0].files.length<1){
                alert("未选中图片")
                return false
            }
            for (var i=0;i<$("#files")[0].files.length;i++){
                postdata.append("files",$("#files")[0].files[i])
            }
            $.ajax({
                type:"POST",
                url:"/file/uploaded",
                data:postdata,
                //返回数据的格式
                datatype: "json",//"xml", "html", "script", "json", "jsonp", "text".
                processData: false,
                contentType: false,
                //成功返回之后调用的函数
                success:function(data){
                    if (data.code == 0) {
                        alert('上传成功:'+data.msg);
                        //window.location.href="/image/imagelist";
                    } else {
                        alert("上传失败:"+data.msg);
                    }
                },
                //调用执行后调用的函数
                complete: function(XMLHttpRequest, textStatus){
                },
                //调用出错执行的函数
                error: function(XMLHttpRequest, textStatus, errorThrown){
                    alert(XMLHttpRequest.readyState + XMLHttpRequest.status + XMLHttpRequest.responseText);
                }
            });
        }
    </script>
    </body>
    </html>

    这个页面上同时展示了单文件上传和多文件上传

    2,uploadadd.html

    <html lang="en">
    <head>
        <script type="text/javascript" language="JavaScript" src="/js/jquery-1.6.2.min.js"></script>
    </head>
    <body>
    <div style="100%;height:20px;background:#ffffff;font-size: 16px;" ></div>
    <div id="content" style="800px;">
        <div style="800px;float:left;">
           <!--====================main begin=====================-->
            <div style="280px;float:left;background: #eeeeee;padding-left: 10px;padding-top: 10px;">
                单文件上传<br/>
                说明:不能多选<br/>
                <form id="form_add" method="POST" action="" enctype="multipart/form-data">
                <div id="filelist" style=" 260px;">
                    <div style="260px;height:50px;background: #ffff00;padding:2px 5px;">
                    <input type="text" style="200px;" name="text1" placeholder="文件说明"/><br/>
                    <input id="file1" type="file" name="file1" />
                    </div>
                </div>
                </form>
                <input type="button" name="gofile" value="追加文件" onclick="go_add()" /><br/><br/>
                <input type="button" name="goupload" value="提交" onclick="go_commit()" />
            </div>
            <!--====================main   end=====================-->
        </div>
    </div>
    <script>
        //最大上传文件数量
        var global_file_max = 10;
        //当前表单中的file数量
        var global_file_num = 1;
        //提交动态生成元素的表单
        function go_commit() {
            var postdata = new FormData($("#form_add")[0]);
            //附加上文件表单元素的数量
            postdata.append("num",global_file_num);
        $.ajax({
            type:"POST",
            url:"/file/uploadadded",
            data:postdata,
            //返回数据的格式
            datatype: "json",//"xml", "html", "script", "json", "jsonp", "text".
            processData: false,
            contentType: false,
            //成功返回之后调用的函数
            success:function(data){
                if (data.code == 0) {
                    alert("success:"+data.msg);
                } else {
                    alert("failed:"+data.msg);
                }
            },
            //调用执行后调用的函数
            complete: function(XMLHttpRequest, textStatus){
            },
            //调用出错执行的函数
            error: function(XMLHttpRequest, textStatus, errorThrown){
                alert(XMLHttpRequest.readyState + XMLHttpRequest.status + XMLHttpRequest.responseText);
            }
        });
    
        }
        //添加一个文件表单元素
        function go_add() {
            var divcss = {
                "background-color": "#ff0000",
                "width":"260px",
                "height":"50px",
                "padding":"2px 5px"
            };
    
            if (global_file_num>=global_file_max) {
                alert('已超过上传文件的数量限制');
                return false;
            }
    
            global_file_num++;
            var parentdiv=$('<div></div>');        //创建一个div
            parentdiv.attr('id','filediv'+global_file_num);
            parentdiv.css(divcss);    //添加css样式
            var divhtml = '<input type="text" style="200px;" name="text'+global_file_num+'" placeholder="文件说明"/><br/>' +
                '<input id="file'+global_file_num+'" type="file" name="file'+global_file_num+'" />';
            parentdiv.html(divhtml);
            $("#filelist").append(parentdiv);
        }
    </script>
    </body>
    </html>

    演示了用jquery动态添加file元素和text元素

    六,测试效果

    1,访问:

    http://127.0.0.1:8080/file/upload

    分别测试单文件上传和多文件上传:

    在文件管理器中查看已上传的文件:

     2,测试表单中包含多个文件域的上传:

    访问:

    http://127.0.0.1:8080/file/uploadadd

    点击 追加文件,添加两个file

     测试提交后,查看控制台:

    filename:file1
    filename:file2
    filename:file3
    text:aaaa
    文件名: qtz.jpg
    text:bbbb
    文件名: qtz2.jpeg
    text:ccc
    文件名: yellowbee.jpeg

    文件名和text说明的对应没有问题

    七,查看spring boot的版本

      .   ____          _            __ _ _
     /\ / ___'_ __ _ _(_)_ __  __ _    
    ( ( )\___ | '_ | '_| | '_ / _` |    
     \/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::        (v2.3.2.RELEASE)
  • 相关阅读:
    观察者模式学习--使用jdk的工具类简单实现
    观察者模式的初始学习--自己实现
    反射 reflect 初始学习
    eclipse java 空心J文件的回复
    linux 命令 more
    spring 3 的 @value的使用
    linux rm 命令
    linux log find 查询
    Resource is out of sync with the file system
    JavaScript(七)数组
  • 原文地址:https://www.cnblogs.com/architectforest/p/13490311.html
Copyright © 2011-2022 走看看