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

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. html基础:DOM操作

    DOM(Document Object Model 文档对象模型) 一个web页面被封装成一个dom对象,通过dom中的js对页面的标签进行操作 一.获取对象 浏览器页面上右键--检查--consol ...

  2. 反向代理搭建隧道,服务器系统为Ubuntu18.04

    该文章参考了实验室师兄写的教程,并记录了自己在实操过程中的坑. 1.内网机器配置 假设现在有一台公用服务器和一台内网服务器,现在想通过反向代理的方式来访问内网服务器.假设公用服务器为A,内网服务器为B ...

  3. 吴恩达《深度学习》-第五门课 序列模型(Sequence Models)-第三周 序列模型和注意力机制(Sequence models & Attention mechanism)-课程笔记

    第三周 序列模型和注意力机制(Sequence models & Attention mechanism) 3.1 序列结构的各种序列(Various sequence to sequence ...

  4. 基于MAXIMO的发电行业EAM解决方案

    1. 行业背景 随着我国以“厂网分开,竞价上网”为特点的电力市场的起步和发展,发电厂.发电集团成为独立企业参与市场竞争,原有的“生产型”管理模式已经不再适应市场的需求.发电企业在重视安全质量.保证电力 ...

  5. RPC概念和框架

    RPC(Remote Procedure Call):远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的思想. RPC 是远程过程调用(Remote Procedur ...

  6. 容器云平台No.9~kubernetes日志收集系统EFK

    EFK介绍 EFK,全称Elasticsearch Fluentd Kibana ,是kubernetes中比较常用的日志收集方案,也是官方比较推荐的方案. 通过EFK,可以把集群的所有日志收集到El ...

  7. 关于KeePass实现mstsc远程桌面(rdp协议)的自动登录

    本文的Keepass版本:KeePass Password Safe Version 2.45 首先介绍一下Keepass,引用官网的解释如下: KeePass is a free open sour ...

  8. 转载:Win7系统 利用 pycharm导入Tensorflow失败,出现报错——ImportError:DLL load failed with error code -1073741795的解决方式

    转载自:https://blog.csdn.net/shen123me/article/details/80621103 下面的报错信息困扰了一天,网上的各种方法也都试过了,还是失败,最后自己瞎试,把 ...

  9. Linux常用命令代码大全

    arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 – (SMBIOS / DMI ...

  10. Mac 效率工具必备神器 —— Alfred

    前言 alfred 这款软件称为「神器」真是当之无愧.今天专门总结一下,作为之前 Mac 配置教程-开发篇 的补充. 需要说明的是,如果你发现我介绍的功能无法使用,则代表需要花钱购买它的 Powerp ...