SpringBoot項目上傳圖片一般是上傳至遠程服務器存儲,開發過程中可能會上傳至當前項目的某個靜態目錄中,此時就會遇到這個問題,文件在上傳之后直接訪問並不能被訪問到,必須重新加載項目。
首先分析一下原因:
我們知道,如果使用類似 /upload/image/1.jpg 這種格式進行圖片的訪問的時候,SpringBoot讀取的並不是本項目中直接的靜態目錄,而是在進行編譯的時候生成target目錄下的文件,如下圖所示:
那么問題就來了,我們在運行的過程中上傳一個圖片的話,並不能重新加載當前這個項目,也就是target目錄下的文件一直是之前的文件,盡管有人說我進行了SpringBoot熱部署(dev-tools),能夠自動重新加載項目,但是問題是熱部署也需要一定的時間去分析和重新加載項目,所以上傳文件后直接進行訪問肯定就不能實現了。
簡單來說:文件只是單純的上傳到項目的文件夾中,並沒有在target目錄下生成對應的文件,導致訪問不到。
在網上看了一個博客,說可以在將文件復制到本地的時候也將文件復制到項目的target目錄下,這樣就可以訪問了,聽着也非常的有道理,但是實踐出真知,經過我的測試,並不能實現,不知道是因為我的問題還是什么,所以並不推薦大家使用這個方法,當然感興趣的也可以測試一下,畢竟這個聽着是真的很有道理。
解決辦法:配置映射路徑攔截器,將虛擬路徑映射為真是圖片地址,達到回顯的目的(已測試,有效)
簡單來說就是將UEditor要訪問的路徑映射成為本地的路徑,廢話不多說直接上代碼:
注:SpringBoot1版本是extends WebMvcConfigurerAdapter類,SpringBoot2版本是implements WebMvcConfigurer,這個地方有點不一樣
1 @Override 2 public void addResourceHandlers(ResourceHandlerRegistry registry){ 3 registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); 4 registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); 5 registry.addResourceHandler("/static/ueditor/**").addResourceLocations("classpath:/static/ueditor/"); 6 registry.addResourceHandler("/public/**").addResourceLocations("classpath:/public/"); 7 registry.addResourceHandler("/static/upload/image/**").addResourceLocations("file:" + UploadUtils.getImgDirFile().getAbsolutePath() + "/"); //添加這一行 8 }
UploadUtils.java
public class UploadUtils { // 項目根路徑下的目錄 -- SpringBoot static 目錄相當於是根路徑下(SpringBoot 默認) public final static String IMG_PATH_PREFIX = "static/upload/image"; public static File getImgDirFile(){ // 構建上傳文件的存放 "文件夾" 路徑 String fileDirPath = new String("src/main/resources/" + IMG_PATH_PREFIX); File fileDir = new File(fileDirPath); if(!fileDir.exists()){ // 遞歸生成文件夾 fileDir.mkdirs(); } return fileDir; } }
重點在於getAbsolutePath()方法,這個函數的作用是獲取當前項目在當前運行環境下的絕對路徑,如我現在在開發過程中獲得的結果就是D:\WorkSpace\IDEA-WorkSpace\......
設置完畢之后就可以正常顯示了。
注:如果你所使用的是SpringBoot多模塊項目,那么通過這個方法獲取到的往往是父項目所在的地址,因此也會出現問題,解決這個問題的辦法是配置當前項目啟動類的工作環境是在具體的某個項目
設置完畢后即可解決這個問題
附:之前在說這個問題的時候,也有人給我提了一個建議,就是不將圖片放置在項目中,而是放置在某個固定的盤符中,這樣返回請求路徑的時候直接請求本地地址,等將來發布到服務器的時候使用Nginx。
不過問題是我對Nginx並不是很了解,所以等我學會了Nginx之后再來完善這個博客吧,你們可以先替我試試好不好用。【手動滑稽】