springMVC文件上传
2019-09-30 本文已影响0人
任未然
一、导包相关包
<properties>
<java.version>1.8</java.version>
<fileupload.version>1.4</commons-fileupload.version>
<lang3.version>3.9</commons-lang3.version>
</properties>
<!-- 文件上传核心包 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${fileupload.version}</version>
</dependency>
<!-- 工具包 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang.version}</version>
</dependency>
二、栗子
控制层
@RestController
public class UploaderController {
//单文件上传
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public String uploadSingleFile(@RequestParam("img") MultipartFile multipartFile) throws IOException {
String imagePath = UploadUtils.saveImage(multipartFile);
return imagePath;
}
//多文件上传
@RequestMapping(value = "/uploads", method = RequestMethod.POST)
public List<String> uploadMultipartFile(@RequestParam("img") MultipartFile[] multipartFiles) throws IOException {
List<String> imgList = new ArrayList<>();
for (MultipartFile multipartFile : multipartFiles) {
String imagePath = UploadUtils.saveImage(multipartFile);
imgList.add(imagePath);
}
return imgList;
}
}
上传工具类
public class UploadUtils {
public static final String SAVE_IMG_FILE = "images";
public static String saveImage(MultipartFile multipartFile) throws IOException {
// 通过配置文件获取保存的路径 注意上线的时候要修改成服务器保存的绝对路径
ResourceBundle bundle = ResourceBundle.getBundle("sys");
//获取到了跟路径
String rootPath = bundle.getString("root.upload.path");
// 获取保存图片名字的统一前缀
String imgSuffix = bundle.getString("img.suffix");
// 生成图片保存路径 根据日期保存
String imagePath = String.format("%s%s%s", SAVE_IMG_FILE, File.separator, DateFormatUtils.format(new Date(), "yyyyMMdd"));
/**
* 保存到服务器数据库的路径
*/
String savePath = String.format("%s%s%s", imagePath, File.separator, getFileName(imgSuffix, multipartFile.getOriginalFilename()));
// 拼接保存的路径
// 根路劲 + 业务需求的路径 + 文件名
File imgFile = new File(String.format("%s%s%s",rootPath,File.separator ,savePath));
// 创建保存图片的文件
FileUtils.touch(imgFile);
// 将客服端图片写到文件中
FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), imgFile);
return savePath;
}
/**
* 获取
* @param oldName
* @return
*/
public static String getFileName(String suffixName, String oldName) {
// 对图片进行重命名
String prefix = suffixName + DateFormatUtils.format(new Date(), "yyyyMMddHHmmss");
String suffix = oldName.substring(oldName.indexOf("."));
return prefix + suffix;
}
}
配置文件
sys.properties
# 文件上传相关路径
# 主路径 (一般是web工程的根目录绝对路径)
root.upload.path=/Users/xxx/xxx/upload
# 图片名前缀
img.suffix = IMG_
file_suffix = FILE_
mvc配置文件
<!--注意id的值是固定的 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 默认编码 -->
<property name="defaultEncoding" value="UTF-8" />
<!-- 文件大小最大值 -->
<property name="maxUploadSize" value="52428800" />
<!-- 单个文件限制大小 -->
<property name="maxUploadSizePerFile" value="5242880"/>
<!-- 内存中缓存的最大值 -->
<property name="maxInMemorySize" value="10240" />
<!-- 为true时,启用推迟文件解析,以便在UploadAction中捕获文件大小异常-->
<property name="resolveLazily" value="true"/>
</bean>
前端
注意:
- 为了能上传文件,必须将表单的method设置为POST或者PUT
- 将enctype设置为multipart/form-data
<h2>单文件上传</h2>
<form id='uploadForm' method="post" enctype="multipart/form-data">
<input type="file" name="img">
<button id='upload'>上传</button>
</form>
<h2>多文件上传</h2>
<form method="post" enctype="multipart/form-data">
<input type="file" name="imgs" multiple>
<button id='upload'>上传</button>
</form>
ajax
//如果没有按钮可以用: $("#upload").change(function(){})
$('#upload').click(function () {
let formData = new FormData($('#uploadForm')[0]);
$.ajax({
url:'http://localhost:8080/upload/',
dataType:'json',
type:'POST',
data: formData,
// 使数据不做处理
processData : false,
// 不要设置Content-Type请求头
contentType : false,
success: function(data){
if (data.status == 'ok') {
alert('上传成功!');
}
},
error:function(response){
console.log(response);
}
});
})
三、核心类介绍
MultipartFile
方法 | 说明 |
---|---|
InputStream getInputStream() | 获取文件流 |
getOriginalFilename() | 获取上传文件的原名 |
boolean isEmpty() | 判断文件是否为空 |
void transferTo(File dest) | 保存文件到指定的文件中,注意父路径一定要存在 |
String getContentType() | 获取文件MIME类型 |
CommonsMultipartResolver
属性 | 说明 |
---|---|
uploadTempDir | 设置上传文件时的临时目录,默认是Servlet容器的临时目录。 |
maxUploadSize | 设置允许上传的总的最大文件大小,以字节为单位计算。当设为-1时表示无限制,默认是-1 |
maxUploadSizePerFile | maxUploadSizePerFile是限制每个上传文件的大小 |
maxInMemorySize | 设置在文件上传时允许写到内存中的最大值,以字节为单位计算,默认是10240 |
resolveLazily | 为true时,启用推迟文件解析,以便在UploadAction中捕获文件大小异常。 |
defaultEncoding | 表示用来解析request请求的默认编码格式,当没有指定的时候根据有些时候Servlet规范会使用默认值ISO-8859-1。当request自己指明了它的编码格式的时候就会忽略这里指定的 |
四、总结
前端
- 请求方式一定要是post请求或者put请求
- 请求的conentType必须是 multipart/form-data
文件
- 对图片进行重命名,一般根据时间戳或者uuid生成规则,避免文件覆盖的现象
- 保存的路径也根据实际的业务场景来动态生成
多文件上传
- 使用MultipartFile[]数组来接受,使用集合来接受保存的路径