springBoot搭建的微服务平台,项目部署在linux上,自部署上线以来一直没有毛病,突然有一天上传出现问题,并且后台不报任何日志,根本无从下手解决。最后通过抓包发现总是报异常500的错误,而报500异常的错误是:
org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException: The temporary upload location [/tmp/tomcat.7659989728636105816.80/work/Tomcat/localhost/ROOT] is not valid
目录非法,这就奇怪了,百度了半天无果。问了公司的“高人”,都没有遇见相关的错误,甚至提出在上传之前,先判断该目录是否存在,这样的改动更大,对于上线后的项目更是不可以。再次之下,便自己又踏上了必应的道路,最后找见一篇很好的博客,完美的诠释了这个问题,特此感谢这位博客的主人,下面是此灰灰博主的链接:http://spring.hhui.top/spring-blog/2019/02/13/190213-SpringBoot文件上传异常之提示The-temporary-upload-location-xxx-is-not-valid/。这位博主写的很清楚,解决了我的问题。
下面说说我的理解,在微服务即springBoot项目场景中,因为部署该项目并没有一个所谓的容器,
所以便在Linux的临时目录/tmp下搭建了一个临时路径,在此可理解为缓存。该tmp下的内容在默认情况下,
是会每个一定时间删除下面的内容的。所以当临时文件的目录被删除后,上传文件找不到指定的目录,便会
报错,目录是无效非法的。
所以我的解决办法是:
其一:
在application.yml中添加了:指定的上传临时路径,
//增加服务配置,自定义baseDir,前提条件:该路径必须存在
server.tomcat.basedir=/tmp/tomcat
其二:
在springBoot的启动类中,加入配置目录。
@Bean
MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
String location=null;
final String dir = System.getProperty("user.dir");
//判断系统来源是linux还是win
String os = System.getProperty("os.name");
if(os.toLowerCase().startsWith("win")){
location=dir+"\\tmp";
}else{
location ="/tmp/tomcat";
}
File tmpFile = new File(location);
if (!tmpFile.exists()) {
tmpFile.mkdirs();
}
factory.setLocation(location);
return factory.createMultipartConfig();
}
个人感觉第二种方法更靠谱,因为你可以在任何情况下,确保该临时目录都存在。而第一种万一服务器删除临时目录时,便会上传不成功。纯属自己学习,这个问题后续还需要什么研究源码,究竟是什么原因,到底哪一种更好。这都是需要去学习的。