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

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="width:100%;height:20px;background:#ffffff;font-size: 16px;" ></div>
<div id="content" style="width:800px;">
<div style="width:800px;float:left;">
<!--====================main begin=====================-->
<div style="width: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="width: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="width:100%;height:20px;background:#ffffff;font-size: 16px;" ></div>
<div id="content" style="width:800px;">
<div style="width:800px;float:left;">
<!--====================main begin=====================-->
<div style="width: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="width: 260px;">
<div style="width:260px;height:50px;background: #ffff00;padding:2px 5px;">
<input type="text" style="width: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="width: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)

spring boot:单文件上传/多文件上传/表单中多个文件域上传(spring boot 2.3.2)的更多相关文章

  1. C#--图片上传(PC端和APP)保存及 跨域上传说明

    手动跨域操作文件 补录:跨域访问文件夹文件是一种常见的需求,下面主要介绍的的通过代码使用具有权限账号的人来达到跨域操作文件的能力. 现在补充一下普通的一些需求场景,今天就遇到了一种需要经常需要登录远程 ...

  2. ASM时的OFM特性对影的建数据文件名称的影响及为SYSTEM表空间的数据文件使用别名

    客户遇到个DG的问题,存储使用的ASM管理,有多个磁盘盘. 在主库创建数据文件,备库自己主动创建的数据文件都在同一磁盘组,而且在主库创建数据文件是指定的是类似**.DBF的名字,到备库也变成了使用AS ...

  3. form表单action提交表单,页面不跳转且表单数据含文件的处理方法

    在最近的项目中需要将含 input[type='file']的表单提交给后台 ,并且后台需要将文件存储在数据库中.之前所用的方法都是先将文件上传到七牛服务器上,然后七牛会返回文件的下载地址,在提交表单 ...

  4. Spring 获取单例流程(二)

    读完这篇文章你将会收获到 Spring 中 prototype 类型的 bean 如何做循环依赖检测 Spring 中 singleton 类型的 bean 如何做循环依赖检测 前言 继上一篇文章 S ...

  5. Oracle数据库表空间与数据文件的关系描述正确的是( )

    Oracle数据库表空间与数据文件的关系描述正确的是( ) A.一个表空间只能对应一个数据文件 B.一个表空间可以对应多个数据文件 C.一个数据文件可以对应多个表空间 D.表空间与数据文件没任何对应关 ...

  6. 查看Oracle数据库表空间大小(空闲、已使用),是否要增加表空间的数据文件

    查看Oracle数据库表空间大小(空闲.已使用),是否要增加表空间的数据文件 1.查看表空间已经使用的百分比 Sql代码 select a.tablespace_name,a.bytes/1024/1 ...

  7. 查看Oracle数据库表空间大小,是否需要增加表空间的数据文件

    在数据库管理中,磁盘空间不足是DBA都会遇到的问题,问题比较常见. --1查看表空间已经使用的百分比 Sql代码 select a.tablespace_name,a.bytes/1024/1024 ...

  8. Spring MVC-表单(Form)标签-文件上传(File Upload)示例(转载实践)

    以下内容翻译自:https://www.tutorialspoint.com/springmvc/springmvc_upload.htm 说明:示例基于Spring MVC 4.1.6. 以下示例显 ...

  9. 曹工说Spring Boot源码(16)-- Spring从xml文件里到底得到了什么(aop:config完整解析【上】)

    写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...

随机推荐

  1. pyhton:time模块和datetime模块

    一.time模块 1.相关定义: time模块时间的表达有3种,时间戳,时间元祖,格式化时间 #时间戳: print(time.time())#获取当前时间戳.时间戳的计算是1970纪元后经过的浮点秒 ...

  2. 微信小程序常用样式

    1.设置全局字体样式app.wxss: text{ font-family:MicroSoft yahei; } 2.设置弹性盒子模型: .container{ /*弹性模型*/ display:fl ...

  3. Solaris – configure ftp server

    SUN Solaris FTPSUN Solaris comes with ftp daemon based on WU-FTPd Washington University project.Whil ...

  4. 吴恩达《深度学习》-课后测验-第三门课 结构化机器学习项目(Structuring Machine Learning Projects)-Week1 Bird recognition in the city of Peacetopia (case study)( 和平之城中的鸟类识别(案例研究))

    Week1 Bird recognition in the city of Peacetopia (case study)( 和平之城中的鸟类识别(案例研究)) 1.Problem Statement ...

  5. 软件开发过程中常用的环境解释DEV FAT UAT PRO

    1.DEV Development environment 开发环境,用于开发者调试使用 2.FAT Feature Acceptance Test environment 功能验收测试环境,用于软件 ...

  6. hadoop文件系统上的小文件合并-Hadoop Archives

    1. 什么是Hadoop archives Hadoop archives是特殊的档案格式.一个Hadoop archive对应一个文件系统目录. Hadoop archive的扩展名是.har.Ha ...

  7. Linux实战(1):装机一键设置脚本-初级版

    #!/bin/bash #此脚本作用是装完centos后所执行的一系列设置,基本是必须设置的操作,主要分为几大功能:修改yum源,安装ifconfig,安装ping,修改selinux配置 #第一部分 ...

  8. 集群实战(1):swarm安装记述

    查看主机名 hostnamectl 修改主机名 hostnamectl set-hostname xxx 关闭selinux sed -i 's/SELINUX=enforcing/#SELINUX= ...

  9. Chrome使用video无法正常播放MP4视频的解决方案

    H5的video标签让前端开发者用一行代码就可以实现视频和音频的播放,然而,有时候我们会突然发现,某些Mp4格式的视频在Chrome下居然无法正常播放?这究竟是什么原因呢?这篇文章主要分析了部分Mp4 ...

  10. kafka-Reblance

    谁来执行Rebalance以及管理consumer的group呢 coordinator来执行对于consumer group的管理,当consumer group的第一个consumer启动的时候, ...