背景
由于在做业务开发的时候常常会碰到文件上传的功能需求,而其实很多时候自己做过一遍又忘记了,又忘记具体在哪个接口用到了,然后查询很多资料都是零零碎碎的千篇一律(当然也不排除一些博客写的好的,只是个人整理更能增加记忆并且符合自己的经历),为了之后的业务开发又涉及到相关功能方便查找起来快捷,特按照自己的方式总结一下,另外也方便大伙参考。
说明
这篇文章我主要从我实际碰到文件上传的三种情况展开,因为这些是我实际工作中遇到较多的情况。
第一种情况 —— 单文件上传,这个没什么好说的。
第二种情况 —— 多文件上传,这种方式不考虑文件业务要求的顺序,每次上传都由客户端全量进行提交多文件的二进制文件,并且文件的顺序由客户端的数组进行决定。
第三种情况
注意: 此篇文章中只是会写出所涉及的核心片段内容,不会把所需的依赖内容和具体详细配置都写出来,也不会涉及
MAVEN
、Spring
、Spring MVC
详细内容,如果觉得有疑惑的地方可以从我的代码库获取这个例子的示例代码查看;代码地址为:https://github.com/caryyu/springmvc-fileuploading。
调试方式
在服务搭建好之后,我们需要调试接口调用情况,命令行用的最多的是curl
,但是本文这里采用并推荐的工具是POSTMAN
—— 此工具只是Chrome
浏览器的一个插件,直接在插件市场安装就可以了,方便我们调试。
注意:文件上传调用时,务必将请求设置为
form-data
表单提交方式,切记,切记!
上传配置
Spring MVC
文件上传有一个配置项,需要在相应的webmvc-config.xml
(配置文件名称随自己项目的xml
名决定) 初始化bean
类型org.springframework.web.multipart.commons.CommonsMultipartResolver
类,并且bean
名称必须固定是multipartResolver
,参考如下:
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 1024*1024*100=104857600即100M(单位:字节) -->
<property name="maxUploadSize" value="1048576000" />
<property name="defaultEncoding" value="UTF-8"/>
</bean>
第一种情况(单文件上传)
由于单文件上传的使用方式最普遍也是最简单的,我这里也不太多介绍了,直接列出接口定义代码如下:
/**
* 单文件上传示例
* @param multipartFile
* @return
*/
@RequestMapping(path = "/fileUploading",method = RequestMethod.POST)
public String fileUploading(
@RequestParam("multipartFile") MultipartFile multipartFile)
throws IOException {
String suffix = FilenameUtils.getExtension(multipartFile.getOriginalFilename());
String fullPath = wrapFullPath(getAutoGenFileName(suffix));
File target = new File(fullPath);
target.getParentFile().mkdirs();
FileCopyUtils.copy(multipartFile.getBytes(),target);
return fullPath;
}
根据上述接口的定义,我们利用POSTMAN
的调用图片如下。
温馨提示:如果图片查看不是很清楚的话可以用浏览器新窗口打开以下图片地址。
第二种情况(多文件上传)
全量文件上传新增与更新的方式用的较少,也是不怎么推荐的做法,当然如果很多时候为了省事可以选择这种方式,有时候业务代码较繁琐的时候这种方式是最简单最粗暴直接的,呵呵!
/**
* 多文件上传示例(必须全量,且文件有关业务顺序服务端无法有效控制)
* @param multipartFiles
* @return
*/
@RequestMapping(path = "/multiFileUploadingUnableSorting",method = RequestMethod.POST)
public List<String> multiFileUploadingUnableSorting(
@RequestParam("multipartFiles") MultipartFile[] multipartFiles)
throws IOException {
List<String> fileNames = new ArrayList<>();
for (int i = 0; i < multipartFiles.length; i++) {
MultipartFile multipartFile = multipartFiles[i];
String suffix = FilenameUtils.getExtension(multipartFile.getOriginalFilename());
String fullPath = wrapFullPath(getAutoGenFileName(suffix));
File target = new File(fullPath);
target.getParentFile().mkdirs();
FileCopyUtils.copy(multipartFile.getBytes(),target);
fileNames.add(fullPath);
}
return fileNames;
}
根据上述接口的定义,我们利用POSTMAN
的调用图片如下。
温馨提示:如果图片查看不是很清楚的话可以用浏览器新窗口打开以下图片地址。
第三种情况(多文件上传)
这种情况我们需要自定义封装一个MultipartFileForm
表单提交对象,方便我们进行参数传递;如下代码所示:
public class MultipartFileForm {
public static class MultipartFileItem {
private Integer sort;
private MultipartFile multipartFile;
public Integer getSort() {
return sort;
}
public void setSort(Integer sort) {
this.sort = sort;
}
public MultipartFile getMultipartFile() {
return multipartFile;
}
public void setMultipartFile(MultipartFile multipartFile) {
this.multipartFile = multipartFile;
}
}
private List<MultipartFileItem> multipartFileItems;
public List<MultipartFileItem> getMultipartFileItems() {
return multipartFileItems;
}
public void setMultipartFileItems(List<MultipartFileItem> multipartFileItems) {
this.multipartFileItems = multipartFileItems;
}
}
接口定义代码如下:
/**
* 多文件上传示例(可选分量,且文件有关业务顺序服务端可以有效控制)
* @param multipartFileForm
* @return
*/
@RequestMapping(path = "/multiFileUploadingAbleSorting",method = RequestMethod.POST)
public List<String> multiFileUploadingAbleSorting(MultipartFileForm multipartFileForm)
throws IOException {
List<String> lineOfOutput = new ArrayList<>();
for (MultipartFileForm.MultipartFileItem multipartFileItem : multipartFileForm.getMultipartFileItems()) {
Integer sort = multipartFileItem.getSort();
MultipartFile multipartFile = multipartFileItem.getMultipartFile();
String suffix = FilenameUtils.getExtension(multipartFile.getOriginalFilename());
String fullPath = wrapFullPath(getAutoGenFileName(suffix));
File target = new File(fullPath);
target.getParentFile().mkdirs();
FileCopyUtils.copy(multipartFile.getBytes(),target);
lineOfOutput.add( sort + ": " + fullPath);
}
return lineOfOutput;
}
根据上述接口的定义,我们利用POSTMAN
的调用图片如下。
温馨提示:如果图片查看不是很清楚的话可以用浏览器新窗口打开以下图片地址。
SEO
Java 多 文件上传、Spring 多 文件上传、SSH 多 文件上传、SSI 多 文件上传、多 文件上传
其他资料参考
最后
在这里本篇就介绍完了,如果有疑问的地方可以给我留言或者在文中的代码库中提Issue
,我会及时进行答复的,谢谢!