多文件上传:从前台到后台代码实现

Posted 遇见美好,遇见妳

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多文件上传:从前台到后台代码实现相关的知识,希望对你有一定的参考价值。

一、业务场景

   项目中有个功能模块是商品管理,其中需要使用到图片上传,而且是多文件上传,这是比较常规的操作,就自己来写这个功能。

商品管理这个功能,除去图片操作之外,常规的增、删、改、查很快完成,然后在把图片相关操作添加进来。

二、需求分析

   自己以前开发的项目中,涉及文件上传的功能倒是不少,可是涉及多文件上传的功能还真没有接触过。可是这不影响自己来做

这个功能,正好可以借此机会学习学习如何实现多文件上传的功能。要点有两个,一个是前端代码怎么添加多个文件,一个是后台

如何来接收多个文件。搞清楚这两个问题之后,剩下的事情会简单得多。

三、解决方案

  自己首先完成多文件上传的前端代码,核心代码是创建一个FormData对象,然后获取页面中选择的文件数组之后,

循环遍历添加多个文件,并且多个文件是添加到同一个字段上,代码如下

var formData = new FormData();
//循环获取上传个文件
for (var i = 0, len = $("#upload_file")[0].files.length; i < len; i++)
var dataTemp = $("#upload_file")[0].files[i];
//console.log("dataTemp--->", dataTemp);
var fileName = dataTemp.name;
var fivarype = fileName.substring(fileName.lastIndexOf(\'.\')).toLowerCase();
if(fivarype !== \'.jpg\' && fivarype !== \'.png\')
return layer.msg(\'错误提示:只能上传jpg或者png格式的图片!\');

var fileSize = dataTemp.size;
var limitSize = 2 * 1024 * 1024;
//console.log("fileSize--->", fileSize);
if(fileSize > limitSize)
return layer.msg(\'错误提示:文件大小不能超过2M!\');

formData.append("files", dataTemp);

这样写有一个好处,可以单独判断每一个选中的文件是否符合特定的格式,大小是否符合要求,在前端可以做一个

简单的过滤。将所有的文件对象都添加到files这个字段之上,多单文件上传的时候自己以为只能添加一次,可是做

好这个功能之后,发现它可以添加多次。有的网友是直接添加formData.append("files",$("#upload_file")[0]); 这样也没问题,

只是在选择文件的时候,不会做相关的校验。html代码如下,

<!-- 图片文件选择 -->
<div >
<input type="file" name="file" id="upload_file" onchange="do_upload()" multiple="multiple" accept=".jpg,.png">
</div>

上传文件时,自己使用的是ajax请求来发送数据,代码如下,

var loadStatus = layer.load(1);
//提交数据
$.ajax(
url: contextPath + \'/goods/upload\',
type: \'post\',
headers:
\'loginToken\': "Bearer " + localStorage.loginToken
,
data: formData,
cache: false,//上传文件无需缓存
contentType: false,//必须
processData: false,//用于对data参数进行序列化处理 这里必须false
success: function (result)
/**

code: -1
count: null
data: null
message: "未获取到上传文件信息"
status: "失败"
url: null

*/
//console.log("result--->", result);
if (result.code === 0)
layer.msg("提示信息:图片上传成功!");
var tempArr = result.data;
for(var i = 0, len = tempArr.length; i < len; i++)
filePathList[filePathList.length] = tempArr[i];

//console.log("图片上传-filePathList--->", filePathList);
handlerShowPicture();
else
layer.msg("错误提示: 图片上传失败");


$("#upload_file").parent().html(\'<input type="file" name="file" id="upload_file" onchange="do_upload()" multiple="multiple" accept=".jpg,.png">\');
layer.close(loadStatus);
// setTimeout(function ()
// //延迟1 s 在关闭弹出窗口
// layer.closeAll();
// , 1000);
,
error: function ()
layer.msg(\'错误提示:上传图片出现异常,请稍后重试!\');
layer.close(loadStatus);
// setTimeout(function ()
// //延迟1 s 在关闭弹出窗口
// layer.closeAll();
// , 1000);
$("#upload_file").parent().html(\'<input type="file" name="file" id="upload_file" onchange="do_upload()" multiple="multiple" accept=".jpg,.png">\');
,
timeout: 180000,
complete: function ()
//$.messager.progress(\'close\');

);

这种方式简单可用,在写过的很多项目中都是使用这种方式来上传文件。

 

后端代码经过反反复复的摸索之后,操作依赖也并不复杂,一个是接收文件数组的时候,直接在方法的形参中进行接收,代码如下

/**
* @description: 商品图片上传
* @date: 2022/1/28 15:31
* @param : MultipartFile[]
* @return: ResultVO
*/
//@PostMapping("/upload")
@RequestMapping(value="/upload",method= RequestMethod.POST,consumes="multipart/form-data")
public ResultVO uploadFile(@RequestParam MultipartFile[] files)
List<String> filePathList = null;
try
if(files == null)
return ResultVOUtil.error(-1, "文件不存在");


for(int i = 0, len = files.length; i < len; i++)
MultipartFile file = files[i];

long fileSize = file.getSize();

if(fileSize > giftLimitSize || fileSize == 0)
log.error("文件大小超出限制:" + fileSize);
return ResultVOUtil.error(-1, "只能上传大小2M以内的图片");


String fileName = file.getOriginalFilename();
if(StringUtils.isBlank(fileName))
log.error("文件名称错误:" + fileName);
return ResultVOUtil.error(-1, "文件名称错误");


String fileSuffixName = fileName.substring(fileName.lastIndexOf(".") + 1);
if(!typeSet.contains(fileSuffixName))
log.error("文件后缀名错误:" + fileSuffixName);
return ResultVOUtil.error(-1, "文件后缀名错误");



filePathList = this.goodsManageService.uploadPicture(files);

catch (Exception ex)
log.error("图片上传操作异常--->" + ex.getMessage());
ex.printStackTrace();


log.info("图片上传返回数据为--->" + filePathList);
if(Objects.equal(filePathList, null))
return ResultVOUtil.error(-1, "图片上传操作失败");
else
return ResultVOUtil.success("上传成功", filePathList);



在service中具体的处理逻辑如下,
@Override
public List<String> uploadPicture(MultipartFile[] files) throws Exception
if(files == null)
log.error("参数-files-错误:", files);
return null;


String targetPath = String.join(File.separator, linuxPath, "3");
File tempPath = new File(targetPath);
if(!tempPath.exists())
tempPath.mkdirs();


String destFileName = "";
List<String> filePathList = new ArrayList<String>();
try
for(int i = 0, len = files.length; i < len; i++)
MultipartFile file = files[i];
String fileName = file.getOriginalFilename();

String fileSuffixName = fileName.substring(fileName.lastIndexOf(".") + 1);

destFileName = CommonUtil.getUUID() + "." + fileSuffixName;
String targetFile = String.join(File.separator, targetPath, destFileName);
File destFile = new File(targetFile);
if(!destFile.exists())
destFile.createNewFile();

file.transferTo(destFile);

String returnPath = File.separator + String.join(File.separator, "3", destFileName);
boolean isWin = System.getProperty("os.name").toLowerCase().contains("win");
if(isWin)
//windows 系统 进行路径替换 将 / 替换为 \\\\
returnPath = returnPath.replaceAll("\\\\\\\\", "/");


filePathList.add(returnPath);

catch (Exception ex)
log.error("文件保存异常:" + ex.getMessage());
return null;



return filePathList;

主要做的一个操作就是接收文件数组,然后将文件保存到自己指定的一个目录下面即可,核心代码是

file.transferTo(destFile);file表示文件数组中的对象,destFile表示目标文件的全路径,包含文件后缀名,
这句代码的含义就是将上传的文件保存到指定的文件当中。最后按照自己业务的要求返回指定的文件路径,不是文件的
全路径,因为在显示图片的时候传的参数是一个相对路径,后台处理的时候加上路径前缀即可。图片显示的方法如下,
public void showPicture(String filePath, HttpServletResponse response) throws Exception 
if(StringUtils.isBlank(filePath))
log.error("参数-filePath-错误");
return;

String realPath = linuxPath + filePath;
String result = "-1";
File file = new File(realPath);
response.setContentType("image/jpeg");

try (FileInputStream fis = new FileInputStream(realPath);
OutputStream os = response.getOutputStream();)
int len = 0;
byte[] buffer = new byte[1024];
while ((len = fis.read(buffer)) != -1)
os.write(buffer, 0, len);

os.flush();
catch (Exception ex)
log.error("图片显示服务错误:" + ex.getMessage());

至此整个多文件上传的功能,全部搞定,功能完成,效果如下

 

 

 

 

参考博文:

前端代码

http://www.manongjc.com/detail/22-chxcnufnrzpbzfn.html

后台代码

https://www.cnblogs.com/ainyi/p/11345714.html

以上是关于多文件上传:从前台到后台代码实现的主要内容,如果未能解决你的问题,请参考以下文章

多文件上传以及java后台接受

多文件上传以及java后台接受

前台Jcrop配合后台Graphics实现图片裁剪并上传

MultipartFile文件上传问题

PHP网站后台上传的图片前台怎么不显示,

JavaWeb中实现文件上传的方式有哪些?