一、问题发现
前段之间为了尝鲜,小编将SpringBoot升级到2.3.3
版本,体验了优雅停机
的功能,感觉那是非常的舒服,当然项目升级遇到的问题也不少,比如新版本中去掉了部分依赖,需要自己手动引入等等…
然而最近在上传文件时,发现自己的项目MultipartFile
取不到值,这种问题根据不同的环境出现原因也不同,ex:
- 前后端参数名对应不一致
spring.servlet.multipart.enabled=false
即关闭文件上传支持- 配置文件中指定了文件上传时的大小值问题
- 切换内嵌容器
tomcat
到undertow
的配置问题 spring.servlet.multipart.location=/tmp
指定了临时文件站,但路径不存在- 多次读取
HttpServletRequest
流 - springboot已经有
CommonsMultipartResolver
,需要排除原有的Multipart配置@EnableAutoConfiguration(exclude = {MultipartAutoConfiguration.class})
小编之前配置过多次读取流来解决流只能读一次的问题,如下:
package com.zhengqing.utils;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StreamUtils;
@Slf4j
public class MyMultiReadHttpServletRequest extends HttpServletRequestWrapper {
/**
* 用于将流保存下来
*/
private final byte[] body;
public MyMultiReadHttpServletRequest(HttpServletRequest request) throws IOException {
super(request);
body = StreamUtils.copyToByteArray(request.getInputStream());
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {}
};
}
}
之后小编将springboot版本切换到2.2.0
之前的版本发现可以正常在controller层的方法参数中读到MultipartFile
值,但之后的版本始终拿不到值,具体原因目前暂时未知!!!估计是版本升级后某些配置问题~
二、问题解决
虽然具体原因未知,但是可以用一种曲线救国的方式拿到前端传过来的MultipartFile
参数值,如下:
@PostMapping("/importData")
@ApiOperation("导入数据")
public String importData(@RequestParam(value = "file", required = false) MultipartFile file,
HttpServletRequest request) {
MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());
MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(request);
MultipartFile fileNew = multipartRequest.getFile("file");
return stCrawlerArticleInfoService.importData(fileNew);
}
上传文件时可能还会出现报错:org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: org/apache/commons/fileupload/disk/DiskFileItemFactory
需要添加如下依赖解决:
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
最终如下取到上传的文件数据:
今日分享语句:这世上,没有谁活得比谁容易,只是有人在呼天抢地,有人在默默努力。