配置
默认情况下Spring Boot无需做任何配置也能实现文件上传的功能,但有可能因默认配置不符而导致文件上传失败问题,所以了解相关配置信息更有助于我们对问题的定位和修复;
# 是否支持批量上传 (默认值 true)
spring.servlet.multipart.enabled: true
# 上传文件的临时目录 (linux的默认临时目录定时会被删除会导致上传失败,尽量指定临时目录)
spring.servlet.multipart.location:
# 上传文件最大为 1M (默认值 1M 根据自身业务自行控制即可)
spring.servlet.multipart.max-file-size: 1MB
# 设置总上传的数据大小 10M(默认值10M 根据自身业务自行控制即可)
spring.servlet.multipart.max-request-size: 1MB
# 文件大小阈值,当大于这个阈值时将写入到磁盘,否则存在内存中,(默认值0 一般情况下不用特意修改)
spring.servlet.multipart.file-size-threshold: 0
注意springboot2的max-file-size、max-request-size只支持大写的KB、MB、GB
或者
增加Bean配置 ,当前类上需要加注解@Configuration,不然扫不到就不会起作用了。 一般配置就放在启动类中就好
@Configuration
public class multipartConfig {
@Bean
MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
String location = System.getProperty("user.dir") + "/data/tmp";
File tmpFile = new File(location);
if (!tmpFile.exists()) {
tmpFile.mkdirs();
}
DataSize maxFileSize = DataSize.of(1,DataUnit.MEGABYTES);//1M
DataSize maxRequestSize = DataSize.of(1,DataUnit.MEGABYTES);//1M
factory.setLocation(location);
factory.setMaxFileSize(maxFileSize);
factory.setMaxRequestSize(maxRequestSize);
return factory.createMultipartConfig();
}
}
控制层
创建一个FileUploadController,@PostMapping相关方法则是对应的单文件上传、多文件上传、BASE64编码三种处理方式。
@RequestParam(“file”)此处的"file"对应的就是html 中 name=“file” 的 input 标签,而将文件真正写入的还是借助的commons-io中的FileUtils.copyInputStreamToFile(inputStream,file)
@Controller
@RequestMapping("/uploads")
@Slf4j
public class FileUploadController {
/**
* 单文件上传
* @param file
* @return
* @throws IOException
*/
@PostMapping("/upload1")
@ResponseBody
public Map<String, String> upload1(@RequestParam("file") MultipartFile file)
throws IOException {
http://log.info("[文件类型] - [{}]", file.getContentType());
http://log.info("[文件名称] - [{}]", file.getOriginalFilename());
http://log.info("[文件大小] - [{}]", file.getSize());
file.transferTo(new File("D:/Users/" + file.getOriginalFilename()));
Map<String, String> result = new HashMap<>(16);
result.put("contentType", file.getContentType());
result.put("fileName", file.getOriginalFilename());
result.put("fileSize", file.getSize() + "");
return result;
}
/**
* 多文件上传
* @param files
* @return
* @throws IOException
*/
@PostMapping("/upload2")
@ResponseBody
public List<Map<String, String>> upload2(@RequestParam("files") MultipartFile[] files)
throws IOException {
if (files == null || files.length == 0) {
return null;
}
List<Map<String, String>> results = new ArrayList<>();
for (MultipartFile file : files) {
// TODO Spring Mvc 提供的写入方式
file.transferTo(new File("D:/Users/" + file.getOriginalFilename()));
Map<String, String> map = new HashMap<>(16);
map.put("contentType", file.getContentType());
map.put("fileName", file.getOriginalFilename());
map.put("fileSize", file.getSize() + "");
results.add(map);
}
return results;
}
@PostMapping("/upload3")
@ResponseBody
public void upload2(String base64) throws IOException {
// TODO BASE64 方式的 格式和名字需要自己控制
// (如 png 图片编码后前缀就会是 data:image/png;base64,)
final File tempFile = new File("D:/Users/test.jpg");
// TODO 防止有的传了 data:image/png;base64, 有的没传的情况
String[] d = base64.split("base64,");
final byte[] bytes = Base64Utils.decodeFromString(d.length > 1 ? d[1] : d[0]);
FileCopyUtils.copy(bytes, tempFile);
}
}
上传测试可以用postman,这不提供上传页面。