代码如下
private static final String TMP = System.getProperty("java.io.tmpdir") + File.separator; // On Windows: java.io.tmpdir:[C:\Users\用户名\AppData\Local\Temp\]
/**
* 可支持多文件上传。
* <p>
* #文件写入磁盘的阈值 spring.servlet.multipart.file-size-threshold: 0
* # 最大文件大小 spring.servlet.multipart.max-file-size: 200MB
* # 最大请求大小 spring.servlet.multipart.max-request-size: 215MB
*
* @param multipartFile
*/
@PostMapping(value = "/testMultipartFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public String testMultipartFile(
@RequestParam(value = "files", required = true) List<MultipartFile> multipartFile) {
String fileName = multipartFile.get(0).getOriginalFilename();
String pathname = TMP + fileName;
try {
multipartFile.get(0).transferTo(new File(pathname));
} catch (Exception e) {
log.error("testMultipartFile exception!", e);
}
return fileName;
}
@PostMapping(value = "/upload")
public String upload(HttpServletRequest request) {
MultipartHttpServletRequest multipartRequest = WebUtils.getNativeRequest(request,
MultipartHttpServletRequest.class);
multipartRequest.getFileNames().forEachRemaining(t -> log.info(t));
List<MultipartFile> multipartFiles = multipartRequest.getFiles("file[]");
MultipartFile[] multipartFile = multipartFiles.toArray(new MultipartFile[0]);
String fileName = multipartFile[0].getOriginalFilename();
String pathname = TMP + fileName;
return pathname;
}
@PostMapping(value = "/file/upload")
public void upload(@RequestParam String name, @RequestPart("file") MultipartFile file) throws IOException {
byte[] data = file.getBytes();
ExceptionUtil.throwException(data == null || data.length == 0, "文件数据不能为空!");
String originalFilename = file.getOriginalFilename();
//获取后缀
String substring = originalFilename.substring(originalFilename.lastIndexOf("."));
ExceptionUtil.throwException(!".doc".equalsIgnoreCase(substring) && !".docx".equalsIgnoreCase(substring), "只能上传doc或docx类型文件");
int length = data.length;
data = GZIPUtils.compress(data);
System.out.println(name + "压缩前: " + length + " 压缩后: " + data.length);
}
@Data
@Valid
private static class SheetDTO {
@NotBlank(message = "sheet名称不能为空")
String name;
@NotNull(message = "表的类型不能为空")
Integer topic;
@NotEmpty(message = "标题行不能为空")
List<Integer> indexList;
}
/**
* sheet表的标题 requestParam入参结构:[{"name":"信息表","topic":1,"indexList":[1,2,3]}]
*
* @param requestParam 额外的复杂参数需要: 用form-data传入json文本 eg. requestParam:[{"name":"情况表","topic":5,"indexList":[1,2,3]}]!
* 在url后拼接参数对简单类型可以处理,但复杂入参(eg. 复合多层级对象)无法模拟出! 代码里@RequestPart和@RequestParam都能接收
* @return
*/
@GetMapping("/sheetColumn")
public void sheetColumn(@RequestPart("requestParam") String requestParam, @RequestPart("file") MultipartFile file, HttpServletRequest request) {
System.out.println(requestParam);
System.out.println(file.getOriginalFilename());
List<SheetDTO> list = JSON.parseArray(requestParam, SheetDTO.class);
String tmp = request.getParameter("requestParam");
System.out.println(tmp);
}
/**
* @param dto 用form-data传入值对:
* name:name
* topic:1
* indexList:1
* indexList:2
* indexList:3
*/
@GetMapping("/sheetColumn2")
public void sheetColumn2(@Valid SheetDTO dto, @RequestPart("file") MultipartFile file) {
System.out.println(file.getOriginalFilename());
}
前端使用 Content-Type = "multipart/form-data" + POST 方式发起请求。
简单类型的集合传入示例见下图'indexList'
接收时的request对象是 org.springframework.web.multipart.support.StandardMultipartHttpServletRequest :
multipartParameterNames: 额外的参数
multipartFiles: 上传的文件组
ServletRequest: 原始的request对象
application.yml
spring.servlet.multipart:
max-file-size: 10MB # 文件的最大大小
max-request-size: 50MB # 请求的最大大小
file-size-threshold: 0 # 文件大小阈值,当大于这个阈值时将写入到磁盘,否则在内存中。 默认值为0
nginx 方面:
需要设置保存临时文件的有读写权限目录,并调整所需内存大小。
error_log /data/logs/error/nginx_error.log info; # 配置异常日志文件
http
{
sendfile on; # 开启高效文件传输模式
client_max_body_size 100m; # 默认 1M,表示客户端请求服务器最大允许大小。 如果请求的正文数据大于client_max_body_size,HTTP协议会报错 413 Request Entity Too Large。
client_body_buffer_size 2m; # Nginx分配给请求数据的Buffer大小。如果请求的数据小于client_body_buffer_size直接将数据先在内存中存储,如果请求的值大于client_body_buffer_size小于client_max_body_size,就会将数据先存储到临时文件中。
client_body_temp_path /data/temp_file; # 文件临时目录 需要有可读写权限
log_format access '----$remote_addr - [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_real_ip [$upstream_addr]';
access_log /usr/local/nginx/log/access.log access; # 请求日志
#Limit
limit_req_zone $binary_remote_addr zone=xxx:10m rate=5r/s; # 限流
}
否则报错: