Springboot文件上傳出現(xiàn)找不到指定系統(tǒng)路徑的解決
Springboot文件上傳出現(xiàn)找不到指定系統(tǒng)路徑
1、問題描述
關(guān)鍵字:SpringMVC 4.2.4、Spring Boot 1.3.1、Servlet 3.0、文件上傳
報(bào)錯信息:
java.io.IOException: java.io.FileNotFoundException: /tmp/tomcat.273391201583741210.8080/work/Tomcat/localhost/ROOT/tmp/source/IMG_20160129_132623.jpg (No such file or directory)
問題源碼:transferTo方法報(bào)錯
// 前端傳入mulFileSource
// 創(chuàng)建壓縮前源文件
File fileSourcePath = new File("tmp/source/");
File fileSource = new File(fileSourcePath, mulFileSource.getOriginalFilename());
if (!fileSourcePath.exists()) {
fileSourcePath.mkdirs();
}
// 將接收得圖片暫存到臨時文件中
mulFileSource.transferTo(fileSource);
2、問題分析
首先,看源碼中文件定義,相對路徑,預(yù)期路徑應(yīng)該是項(xiàng)目路徑/tmp/source/,但是報(bào)錯確是一個系統(tǒng)臨時文件路徑(tomcat的)。
其次,由于是transferTo方法報(bào)錯,因此應(yīng)該是該方法寫入文件時報(bào)錯,因此,我們跟入方法源碼。
public class StandardMultipartHttpServletRequest extends AbstractMultipartHttpServletRequest {
//中間代碼省略
/**
* Spring MultipartFile adapter, wrapping a Servlet 3.0 Part object.
*/
@SuppressWarnings("serial")
private static class StandardMultipartFile implements MultipartFile, Serializable {
//中間代碼省略
@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
this.part.write(dest.getPath());
package org.apache.catalina.core;
/**
* Adaptor to allow {@link FileItem} objects generated by the package renamed
* commons-upload to be used by the Servlet 3.0 upload API that expects
* {@link Part}s.
*/
public class ApplicationPart implements Part {
//中間代碼省略
@Override
public void write(String fileName) throws IOException {
File file = new File(fileName);
if (!file.isAbsolute()) {
file = new File(location, fileName);
}
try {
fileItem.write(file);
} catch (Exception e) {
throw new IOException(e);
}
}
}
源碼一目了然,使用Servlet3.0的支持的上傳文件功能時,如果我們沒有使用絕對路徑的話,transferTo方法會在相對路徑前添加一個location路徑,即:file = new File(location, fileName);。當(dāng)然,這也影響了SpringMVC的Multipartfile的使用。
由于我們創(chuàng)建的File在項(xiàng)目路徑/tmp/source/,而transferTo方法預(yù)期寫入的文件路徑為/tmp/tomcat.273391201583741210.8080/work/Tomcat/localhost/ROOT/tmp/source/,我們并沒有創(chuàng)建該目錄,因此會拋出異常。
3、問題解決方案
使用絕對路徑
修改location的值
這個location可以理解為臨時文件目錄,我們可以通過配置location的值,使其指向我們的項(xiàng)目路徑,這樣就解決了我們遇到的問題。
在Spring Boot下配置location,可以在main()方法所在文件中添加如下代碼:
/**
* 文件上傳臨時路徑
*/
@Bean
MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
factory.setLocation("/app/pttms/tmp");
return factory.createMultipartConfig();
}
SpringBoot 上傳文件時本地路徑無效
SpringBoot 通過網(wǎng)關(guān)Zuul進(jìn)行附件上傳的時候,有時會出現(xiàn)如下錯誤
[Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.io .IOException: The temporary upload location [/tmp/tomcat.3814974221022613431.8080/work/Tomcat/localhost/ROOT] is not valid] with root causejava.io .IOException: The temporary upload location [/tmp/tomcat.3814974221022613431.8080/work/Tomcat/localhost/ROOT] is not valid
錯誤產(chǎn)生的原因
1、spring boot的應(yīng)用服務(wù)在啟動的時候,會生成在操作系統(tǒng)的/tmp目錄下生成一個Tomcat.*的文件目錄,用于"java.io.tmpdir"文件流操作
TomcatEmbeddedServletContainerFactory
2、程序?qū)ξ募牟僮鲿r:會生成臨時文件,暫存在臨時文件中;長時間不操作,導(dǎo)致/tmp下面的tomcat臨時文件目錄被刪除,
且刪除的文件不可恢復(fù),上傳文件時獲取不到文件目錄,報(bào)錯
解決方式有以下幾點(diǎn)
1.重啟服務(wù);
2.網(wǎng)關(guān)是否引入spring-boot-starter-web依賴,若無,則將其引入;
3、設(shè)置spring.servlet.multipart.enabled:true

4.修改上傳文件默認(rèn)的BaseDir
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
@SpringBootConfiguration重復(fù)加載報(bào)錯問題解決
@SpringBootApplication?注解的?exclude?屬性用于排除特定的自動配置類,而不是用于排除主配置類本身,因此,不能通過?exclude?屬性來排除主配置類的加載,這篇文章主要介紹了@SpringBootConfiguration重復(fù)加載報(bào)錯,需要的朋友可以參考下2024-08-08
java通過AOP實(shí)現(xiàn)全局日志打印詳解
最近自己一直再看現(xiàn)有微服務(wù)的日志模塊,發(fā)現(xiàn)就是使用AOP來做controller層的日志處理,加上項(xiàng)目在進(jìn)行架構(gòu)優(yōu)化,這篇文章主要給大家介紹了關(guān)于java通過AOP實(shí)現(xiàn)全局日志打印的相關(guān)資料,需要的朋友可以參考下2022-01-01
java中將一個List等分成n個list的工具方法(推薦)
下面小編就為大家?guī)硪黄猨ava中將一個List等分成n個list的工具方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03
java連接Mongodb實(shí)現(xiàn)增刪改查
這篇文章主要為大家詳細(xì)介紹了java連接Mongodb實(shí)現(xiàn)增刪改查,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-03-03
IDEA自定義setter和getter格式的設(shè)置方法
這篇文章主要介紹了IDEA自定義setter和getter格式的設(shè)置方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友參考下吧2023-12-12

