上文简单介绍了springmvc单文件上传表单 ,本文继续介绍多文件上传表单。包含单文件上传的表单已经能够满足大部分功能需求,但任然不够完善。实际业务中可能会包含多个文件同时上传,例如:商家在电商平台申请店铺需要上传身份证扫描文件,这时会有两份上传文件(正/反面)。此时,单文件表单就不能满足需求了;当然你也可以把多个文件拆分为多个表单,关于业务实际问题不在本文讨论范围之内。
在很多时候并不是说问题本身有多难,难的是把问题找出来。只要能把疑问命题找到,距离解决问题也就相差0.1毫米;所以,springmvc 对多文件上传这个问题域有多种解决方案,下面介绍 springmvc 是如何支持多文件上传的!
方案一:使用数组接受表单文件 org.springframework.web.multipart.MultipartFile[]
- 创建多个文件域,当前测试用例表单中文件域数据不固定
<!-- 定义表单结构 -->
<div id="normal_form" class="form"><!-- 多文件上传 -->
<h2 class="intro">C. 多文件上传表单</h2>
<form class="hidden" action="<%=basePath %>form/uploadMore.do" method="post" enctype="multipart/form-data">
<p>
<label for="upFile1">选择要上传的文件:</label>
<input type="file" name="multipartFiles" />
</p>
<p>
<input type="button" id="addFileItem" value="Add File Item" />
<input type="submit" value="Submit" />
</p>
</form>
</div><!-- /多文件上传 -->
window.console && console.log("form.js");
$(function() {
var thisPageFn = new FormNormalFn();
thisPageFn.initEvents();
thisPageFn.initData();
window.console && console.log("Page load event is complete");
});
/**
* @description form.jsp 页面交互
* @author Huang.Yong
* @version 0.1
* @date 2016年1月5日 - 下午6:16:04
*/
function FormNormalFn() {
var $thisObj = this;
var baseCtt = $("body");
/**
* 初始化事件
*/
this.initEvents = function() {
// 展示隐藏
$(".intro").click(function(){
$(this).parent().find("form").toggleClass("hidden");
});
// 添加上传文件项
$("#addFileItem").click(function(){
var $this = $(this);
var btnCtn = $this.parent();
var p =$("<p/>").insertBefore(btnCtn);
p.append($("<input/>",{
type : "file",
name : "multipartFiles"
})).append($("<input/>",{
type : "button",
value : " X "
}).click(function(){
var $delBtn = $(this);
$delBtn.parent().remove();
}));
});
}
/**
* 初始化数据
*/
this.initData = function() {
}
/**
* 日志记录
*/
function log(msg) {
window.console && console.log(msg);
}
return this;
}
/**
* @Title: uploadMore
* @Description: 多文件上传
* @param multipartFiles
* @return ModelMap
*/
@RequestMapping("/uploadMore")
@ResponseBody
public ModelMap uploadMore(@RequestParam("multipartFiles") MultipartFile[] multipartFiles) {
boolean flag = false;
String message = null;
List<ModelMap> data = Lists.newArrayList();
try {
for (MultipartFile multipartFile : multipartFiles) {
System.out.println(multipartFile.getName() + "-----" + multipartFile.getOriginalFilename());
ModelMap uploadOne = uploadOne(multipartFile);
data.add(uploadOne);
}
flag = true;
} catch (Exception e) {
flag = false;
message = "";
LOGGER.warn(message + " : " + e.getMessage(), e);
}
return WebUtil.getModelMap(flag, data, message);
}
tips:此种方式上传多个文件有两个地方需要特别注意,
①表单类型enctype="multipart/form-data"以及表单名称<input type="file" name="multipartFiles" />;
②控制器参数名称public ModelMap uploadMore(@RequestParam("multipartFiles") MultipartFile[] multipartFiles)
结果验证:
当前选择三个需要上传的文件
断点查看控制器:
由此可见,文件已上传成功!不过此方法有些缺陷:
- 表单文件域名称必须与接口中数组参数名一致
- 只能根据参数 multipartFiles 下标值区分文件,一旦UI中文件域位置调整就会产生严重后果(如:身份证文件与营业执照文件对调等)
方案二:表单实体(FormEntities)+ 请求对象(HttpServletRequest)
<div id="normal_form" class="form"><!-- 复杂文件上传表单 -->
<h2 class="intro">D. 复杂文件上传表单</h2>
<form class="hidden" action="<%=basePath %>form/complexForm.do" method="post" enctype="multipart/form-data">
<p>
<label for="form4_item1" class="title">文本框:</label>
<input type="text" id="form4_item1" class="item" name="formText" />
</p>
<p>
<label for="form4_item2" class="title">密码框:</label>
<input type="password" id="form4_item2" class="item" name="formPwd" />
</p>
<p>
<label>单选:</label>
<input type="radio" id="form1_item3" class="item" name="formRadios" value="rdo1" />
<label for="form1_item3">单选一</label>
<input type="radio" id="form1_item32" class="item" name="formRadios" value="rdo2" />
<label for="form1_item32">单选二</label>
<input type="radio" id="form1_item33" class="item" name="formRadios" value="rdo3" />
<label for="form1_item33">单选三</label>
</p>
<p>
<label>复选:</label>
<input type="checkbox" id="form4_item4" class="item" name="formCheckboxes" value="复选框1" />
<label for="form4_item4" class="title">复选一</label>
<input type="checkbox" id="form4_item5" class="item" name="formCheckboxes" value="复选框2" />
<label for="form4_item5" class="title">复选二</label>
<input type="checkbox" id="form4_item6" class="item" name="formCheckboxes" value="复选框3" />
<label for="form4_item6" class="title">复选三</label>
</p>
<p>
<label for="form4_sl">下拉:</label>
<select name="formSl" id="form1_sl">
<option value="value1">下拉1</option>
<option value="value2">下拉2</option>
<option value="value3">下拉3</option>
<option value="value4">下拉4</option>
<option value="value5">下拉5</option>
</select>
</p>
<p>
<label for="form4_txta" style="left:left;">多行文本:</label>
<textarea name="formTxt" id="form4_txta" cols="30" rows="10" style="resize:none;left:left;"></textarea>
</p>
<p>
<input type="button" class="addFileItem2" value="Add File Item" />
<input type="submit" value="Submit" />
</p>
</form>
</div><!-- /复杂文件上传表单 -->
- 表单事件,点击【Add File Item】添加一个新的文件域,且文件域name值不能相同
// 添加上传文件项
$(".addFileItem2").click(function(){
var $this = $(this);
var btnCtn = $this.parent();
var p =$("<p/>").insertBefore(btnCtn);
p.append($("<input/>",{
type : "file",
name : "multipartFiles_" + (new Date().getTime()) // 每次不同
})).append($("<input/>",{
type : "button",
value : " X "
}).click(function(){
var $delBtn = $(this);
$delBtn.parent().remove();
}));
});
/**
* @Title: complexForm
* @Description: 映射复杂表单
* @param form 表单实体映射
* @param request 请求对象
*/
@RequestMapping("/complexForm")
@ResponseBody
public ModelMap complexForm(SimpleForm form, HttpServletRequest request) {
boolean flag = false;
String message = null;
Map<String, Object> data = Maps.newLinkedHashMap();
try {
// 表单数据
data.put("formData", form);
// 获取附件
// 如果是文件上传: request.getClass() == MultipartHttpServletRequest.class
if (request instanceof MultipartHttpServletRequest) {
MultipartHttpServletRequest multipartReq = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartReq.getFileMap();
// 上传到指定位置
if (MapUtils.isNotEmpty(fileMap)) {
int count = 1;
for (Entry<String, MultipartFile> me : fileMap.entrySet()) {
// 表单项名称
String formItemName = me.getKey();
// 与表单项名称关联的唯一附件
MultipartFile multipartFile = me.getValue();
// do something
ModelMap uploadOne = this.uploadOne(multipartFile);
data.put(formItemName + count, uploadOne);
count++;
}
}
}
flag = true;
} catch (Exception e) {
flag = false;
message = "";
LOGGER.warn(message + " : " + e.getMessage(), e);
}
return WebUtil.getModelMap(flag, data, message);
}
Tips:使用此种方式上传多个文件附件时,文件域name值不能一致(name作为 Map 的 Key 值);如果可以确定一致性,则推荐使用方案一;
结果验证:
选择需要上传的文件:
断点控制器观察文件列表:
通过结果观察表单其他数据:
至此,关于 springmvc 表单映射已记录完成;其中更多细节部分可以下载附件:ssmFU.zip(maven)查阅研究,欢迎留言探讨学习。
- 大小: 26.2 KB
- 大小: 25.7 KB
- 大小: 18.8 KB
- 大小: 58.8 KB
- 大小: 44 KB
分享到:
相关推荐
NULL 博文链接:https://dayongge.iteye.com/blog/2268976
NULL 博文链接:https://dayongge.iteye.com/blog/2268894
NULL 博文链接:https://wujiu.iteye.com/blog/2012300
springmvc form表单的使用。 简单的说明了如何使用form表单并绑定pojo,包括主子表的form请求到一个pojo
Servlet、Struts、SpringMVC对于表单重复提交的解决方案
springMVC文件上传完美 demo,自带 jar包, 前后台代码 ,表单上传,项目直接导入即可!
SpringMVC表单标签简介
SpringMVC入门很简单之表单标签,具体参考博文: http://www.cnblogs.com/liukemng/tag/SpringMVC/
springmvc 第二个例子(接收表单参数+重定向)
springmvc的服务器表单校验所需要的jar包,分别为:classmate.jar、classmate.jar、hibernate-validator-annotation-processor-5、hibernate-validator-annotation-processor-5、validation-api-1.1.0.jar
本项目为springMVC表单验证简单实例,支持国际化,发布就可以试验效果, 访问路如:http://localhost:8080/springMVC_Validator/register.mvc
假如今天配置新的一个组件,称之为文件解析器,再点上传的时候,控制器会调用文件解析器,文件解析器可以帮助我们解析请求,解析request,解析完request,可以拿到上传文件项,就可以返回一个upload。后面继续执行...
/login2.do"提交表单页面发送login2.do请求,而LoginControlle类中r的@RequestMapping("/login2.do")注解请求映射路径login2.do进行转发;前提是页面表单提交那个请求路径,就要在LoginController类中注释掉该请求...
SpringMVC之简单使用,利用jsp技术实现简单的表单验证和网页登录
这是我的这篇博文的源码:SpringMVC与SiteMesh2.4无缝整合并借助JSR303规范实现表单验证,博文地址:http://blog.csdn.net/jadyer/article/details/7574668
使用ajaxSubmit文件上传。
为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器。 一旦设置了enctype为multipart/form-data,...
本篇文章主要介绍了springMVC中基于token防止表单重复提交方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
文件上传是Web应用程序中常见的功能之一,Spring MVC提供了方便的机制来处理文件上传。下面是关于Spring MVC实现文件上传的详细描述: Spring MVC文件上传的实现步骤如下: 准备MultipartResolver: 在Spring MVC...