• SpringMVC之多文件上传表单


    上文简单介绍了springMVC之单文件上传 ,本文继续介绍多文件上传表单。包含单文件上传的表单已经能够满足大部分功能需求,但任然不够完善。实际业务中可能会包含多个文件同时上传,例如:商家在电商平台申请店铺需要上传身份证扫描文件,这时会有两份上传文件(正/反面)。此时,单文件表单就不能满足需求了;当然你也可以把多个文件拆分为多个表单,关于业务实际问题不在本文讨论范围之内。

    在很多时候并不是说问题本身有多难,难的是把问题找出来。只要能把疑问命题找到,距离解决问题也就相差0.1毫米;所以,springmvc 对多文件上传这个问题域有多种解决方案,下面介绍 springmvc 是如何支持多文件上传的!

    方案一:使用数组接受表单文件 org.springframework.web.multipart.MultipartFile[]

    • 创建多个文件域,当前测试用例表单中文件域数据不固定
    Jsp代码  收藏代码
    1. <!-- 定义表单结构 -->  
    2. <div id="normal_form" class="form"><!-- 多文件上传 -->  
    3.     <h2 class="intro">C. 多文件上传表单</h2>  
    4.     <form class="hidden" action="<%=basePath %>form/uploadMore.do" method="post" enctype="multipart/form-data">  
    5.         <p>  
    6.             <label for="upFile1">选择要上传的文件:</label>  
    7.             <input type="file" name="multipartFiles" />  
    8.         </p>  
    9.           
    10.         <p>  
    11.             <input type="button" id="addFileItem" value="Add File Item" />  
    12.             &nbsp;  
    13.             &nbsp;  
    14.             &nbsp;  
    15.             <input type="submit" value="Submit" />  
    16.         </p>  
    17.     </form>  
    18. </div><!-- /多文件上传 -->  
    •  添加事件
    Js代码  收藏代码
    1. window.console && console.log("form.js");  
    2.   
    3. $(function() {  
    4.     var thisPageFn = new FormNormalFn();  
    5.     thisPageFn.initEvents();  
    6.     thisPageFn.initData();  
    7.     window.console && console.log("Page load event is complete");  
    8. });  
    9.   
    10. /** 
    11.  * @description form.jsp 页面交互 
    12.  * @author Huang.Yong 
    13.  * @version 0.1 
    14.  * @date 2016年1月5日 - 下午6:16:04 
    15.  */  
    16. function FormNormalFn() {  
    17.     var $thisObj = this;  
    18.     var baseCtt = $("body");  
    19.   
    20.     /** 
    21.      * 初始化事件 
    22.      */  
    23.     this.initEvents = function() {  
    24.         // 展示隐藏  
    25.         $(".intro").click(function(){  
    26.             $(this).parent().find("form").toggleClass("hidden");  
    27.         });  
    28.           
    29.         // 添加上传文件项  
    30.         $("#addFileItem").click(function(){  
    31.             var $this = $(this);  
    32.             var btnCtn = $this.parent();  
    33.               
    34.             var p =$("<p/>").insertBefore(btnCtn);  
    35.             p.append($("<input/>",{  
    36.                 type : "file",  
    37.                 name : "multipartFiles"  
    38.             })).append($("<input/>",{  
    39.                 type : "button",  
    40.                 value : " X "  
    41.             }).click(function(){  
    42.                 var $delBtn = $(this);  
    43.                 $delBtn.parent().remove();  
    44.             }));  
    45.         });  
    46.     }  
    47.   
    48.     /** 
    49.      * 初始化数据 
    50.      */  
    51.     this.initData = function() {  
    52.     }  
    53.   
    54.     /** 
    55.      * 日志记录 
    56.      */  
    57.     function log(msg) {  
    58.         window.console && console.log(msg);  
    59.     }  
    60.   
    61.     return this;  
    62. }  
    • 定义控制器接口
    Java代码  收藏代码
    1. /** 
    2.  * @Title: uploadMore 
    3.  * @Description: 多文件上传 
    4.  * @param multipartFiles 
    5.  * @return ModelMap 
    6.  */  
    7. @RequestMapping("/uploadMore")  
    8. @ResponseBody  
    9. public ModelMap uploadMore(@RequestParam("multipartFiles") MultipartFile[] multipartFiles) {  
    10.     boolean flag = false;  
    11.     String message = null;  
    12.     List<ModelMap> data = Lists.newArrayList();  
    13.   
    14.     try {  
    15.         for (MultipartFile multipartFile : multipartFiles) {  
    16.             System.out.println(multipartFile.getName() + "-----" + multipartFile.getOriginalFilename());  
    17.             ModelMap uploadOne = uploadOne(multipartFile);  
    18.             data.add(uploadOne);  
    19.         }  
    20.   
    21.         flag = true;  
    22.     } catch (Exception e) {  
    23.         flag = false;  
    24.         message = "";  
    25.         LOGGER.warn(message + " : " + e.getMessage(), e);  
    26.     }  
    27.   
    28.     return WebUtil.getModelMap(flag, data, message);  
    29. }  

     tips:此种方式上传多个文件有两个地方需要特别注意,

      ①表单类型enctype="multipart/form-data"以及表单名称<input type="file" name="multipartFiles" />;

      ②控制器参数名称public ModelMap uploadMore(@RequestParam("multipartFiles") MultipartFile[] multipartFiles)

    结果验证:

    当前选择三个需要上传的文件

     

    断点查看控制器:



     

     由此可见,文件已上传成功!不过此方法有些缺陷:

    1. 表单文件域名称必须与接口中数组参数名一致
    2. 只能根据参数 multipartFiles 下标值区分文件,一旦UI中文件域位置调整就会产生严重后果(如:身份证文件营业执照文件对调等)

    方案二:表单实体(FormEntities)+ 请求对象(HttpServletRequest)

    • 定义复杂表单
    Html代码  收藏代码
    1. <div id="normal_form" class="form"><!-- 复杂文件上传表单 -->  
    2.     <h2 class="intro">D. 复杂文件上传表单</h2>  
    3.     <form class="hidden" action="<%=basePath %>form/complexForm.do" method="post" enctype="multipart/form-data">  
    4.         <p>  
    5.             <label for="form4_item1" class="title">文本框:</label>  
    6.             <input type="text" id="form4_item1" class="item" name="formText" />  
    7.         </p>  
    8.         <p>  
    9.             <label for="form4_item2" class="title">密码框:</label>  
    10.             <input type="password" id="form4_item2" class="item" name="formPwd" />  
    11.         </p>  
    12.         <p>  
    13.             <label>单选:</label>  
    14.             <input type="radio" id="form1_item3" class="item" name="formRadios" value="rdo1" />  
    15.             <label for="form1_item3">单选一</label>  
    16.             &nbsp;  
    17.             &nbsp;  
    18.             <input type="radio" id="form1_item32" class="item" name="formRadios" value="rdo2" />  
    19.             <label for="form1_item32">单选二</label>  
    20.             &nbsp;  
    21.             &nbsp;  
    22.             <input type="radio" id="form1_item33" class="item" name="formRadios" value="rdo3" />  
    23.             <label for="form1_item33">单选三</label>  
    24.         </p>  
    25.         <p>  
    26.             <label>复选:</label>  
    27.             <input type="checkbox" id="form4_item4" class="item" name="formCheckboxes" value="复选框1" />  
    28.             <label for="form4_item4" class="title">复选一</label>  
    29.             &nbsp;  
    30.             &nbsp;  
    31.             <input type="checkbox" id="form4_item5" class="item" name="formCheckboxes" value="复选框2" />  
    32.             <label for="form4_item5" class="title">复选二</label>  
    33.             &nbsp;  
    34.             &nbsp;  
    35.             <input type="checkbox" id="form4_item6" class="item" name="formCheckboxes" value="复选框3" />  
    36.             <label for="form4_item6" class="title">复选三</label>  
    37.         </p>  
    38.         <p>  
    39.             <label for="form4_sl">下拉:</label>  
    40.             <select name="formSl" id="form1_sl">  
    41.                 <option value="value1">下拉1</option>  
    42.                 <option value="value2">下拉2</option>  
    43.                 <option value="value3">下拉3</option>  
    44.                 <option value="value4">下拉4</option>  
    45.                 <option value="value5">下拉5</option>  
    46.             </select>  
    47.         </p>  
    48.         <p>  
    49.             <label for="form4_txta" style="left:left;">多行文本:</label>  
    50.             <textarea name="formTxt" id="form4_txta" cols="30" rows="10" style="resize:none;left:left;"></textarea>  
    51.         </p>  
    52.         <p>  
    53.             <input type="button" class="addFileItem2" value="Add File Item" />  
    54.             &nbsp;  
    55.             &nbsp;  
    56.             &nbsp;  
    57.             <input type="submit" value="Submit" />  
    58.         </p>  
    59.     </form>  
    60. </div><!-- /复杂文件上传表单 -->  
    •  表单事件,点击【Add File Item】添加一个新的文件域,且文件域name值不能相同
    Js代码  收藏代码
    1. // 添加上传文件项  
    2. $(".addFileItem2").click(function(){  
    3.     var $this = $(this);  
    4.     var btnCtn = $this.parent();  
    5.       
    6.     var p =$("<p/>").insertBefore(btnCtn);  
    7.     p.append($("<input/>",{  
    8.         type : "file",  
    9.         name : "multipartFiles_" + (new Date().getTime())  // 每次不同  
    10.     })).append($("<input/>",{  
    11.         type : "button",  
    12.         value : " X "  
    13.     }).click(function(){  
    14.         var $delBtn = $(this);  
    15.         $delBtn.parent().remove();  
    16.     }));  
    17. });  
    • 开发控制器接口
    Java代码  收藏代码
    1. /** 
    2.  * @Title: complexForm 
    3.  * @Description: 映射复杂表单 
    4.  * @param form 表单实体映射 
    5.  * @param request 请求对象 
    6.  */  
    7. @RequestMapping("/complexForm")  
    8. @ResponseBody  
    9. public ModelMap complexForm(SimpleForm form, HttpServletRequest request) {  
    10.     boolean flag = false;  
    11.     String message = null;  
    12.     Map<String, Object> data = Maps.newLinkedHashMap();  
    13.   
    14.     try {  
    15.         // 表单数据  
    16.         data.put("formData", form);  
    17.   
    18.         // 获取附件  
    19.         // 如果是文件上传: request.getClass() == MultipartHttpServletRequest.class  
    20.         if (request instanceof MultipartHttpServletRequest) {  
    21.             MultipartHttpServletRequest multipartReq = (MultipartHttpServletRequest) request;  
    22.             Map<String, MultipartFile> fileMap = multipartReq.getFileMap();  
    23.   
    24.             // 上传到指定位置  
    25.             if (MapUtils.isNotEmpty(fileMap)) {  
    26.                 int count = 1;  
    27.                 for (Entry<String, MultipartFile> me : fileMap.entrySet()) {  
    28.                       
    29.                     // 表单项名称  
    30.                     String formItemName = me.getKey();  
    31.                     // 与表单项名称关联的唯一附件  
    32.                     MultipartFile multipartFile = me.getValue();  
    33.   
    34.                     // do something  
    35.                     ModelMap uploadOne = this.uploadOne(multipartFile);  
    36.                     data.put(formItemName + count, uploadOne);  
    37.                     count++;  
    38.                 }  
    39.             }  
    40.         }  
    41.   
    42.         flag = true;  
    43.     } catch (Exception e) {  
    44.         flag = false;  
    45.         message = "";  
    46.         LOGGER.warn(message + " : " + e.getMessage(), e);  
    47.     }  
    48.   
    49.     return WebUtil.getModelMap(flag, data, message);  
    50. }  

    Tips:使用此种方式上传多个文件附件时,文件域name值不能一致(name作为 Map 的 Key 值);如果可以确定一致性,则推荐使用方案一

    结果验证:

    选择需要上传的文件:

    断点控制器观察文件列表:



    通过结果观察表单其他数据:



     

    至此,关于 springmvc 表单映射已记录完成;其中更多细节部分可以下载附件:ssmFU.zip(maven)查阅研究,欢迎留言探讨学习。

  • 相关阅读:
    如何在EasyDSS内调用的iframe地址设置自动播放?
    雏鹰训练营第一次作业
    211806152 蔡钰玲 http://www.cnblogs.com/211806152Erika/ https://github.com/ErikaSakii
    Python05:while循环
    Python04:简单if逻辑判断
    Python03:用户交互输入格式输出
    Python02:变量
    Python01:HelloWorld
    课后作业(一)
    软工假期预先作业
  • 原文地址:https://www.cnblogs.com/xm1-ybtk/p/5111960.html
Copyright © 2020-2023  润新知