在springboot中,上傳圖片或文件上傳成功後,卻沒法訪問。前端
在springboot中,用相對的路徑儲存,也只是存儲在臨時的目錄,一重啓文件就會沒有了。而且打爲jar後,存入文件也會有問題。java
這時,須要配置一個虛擬路徑,映射到物理路徑上。好比在服務器將文件存在/usr/upload文件夾下,同時映射的路徑爲http://localhost:8080/image。那麼處理上傳文件的後臺程序則寫入文件/usr/upload文件夾下,經過瀏覽器訪問localhost:8080/image/xxx.png,就至關於訪問/usr/upload文件夾的xxx.png。web
具體的實現步驟-》spring
前端使用的參考博客園,使用的是TinyMCE編輯器。粘貼圖片,就能夠上傳。後端
這個異步不是使用form,因此不討論上傳的工具類。瀏覽器
在後端中,處理上傳的handler:springboot
package com.hj.blog.handler; import com.hj.blog.service.UploadService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import java.io.*; @RestController public class UploadHandler { private Logger logger = LoggerFactory.getLogger(UploadHandler.class); @Autowired private UploadService uploadService; @RequestMapping("/uploadimg") public String uploadimg(HttpServletRequest request) throws IOException, ServletException { // handler調用文件上傳的service 獲得文件的虛擬路徑 String filepath = uploadService.uploadImg(request); return filepath; } }
處理文件上傳的service,在service中將上傳的文件夾和映射的文件夾都放在配置文件中:服務器
package com.hj.blog.service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import java.io.*; import java.text.SimpleDateFormat; import java.util.*; @Service public class UploadService { private Logger logger = LoggerFactory.getLogger(UploadService.class); // 文件的真實路徑 @Value("${file.uploadFolder}") private String realBasePath; @Value("${file.accessPath}") private String accessPath; public String uploadImg(HttpServletRequest request) throws IOException, ServletException { InputStream inputStream = request.getInputStream(); //獲取請求頭中Contect-Type的值 // 圖片後綴 String imgSuffix = "png"; Enumeration enumeration=request.getHeaderNames(); while(enumeration.hasMoreElements()) { String name=(String)enumeration.nextElement(); if(name.equals("content-type")){ String value=request.getHeader(name); imgSuffix = value.split("/")[1]; logger.info("header中" + name + " " + value); logger.info("文件後綴:" + imgSuffix); } } // 文件惟一的名字 String fileName = UUID.randomUUID().toString() + "." +imgSuffix; Date todayDate = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); String today = dateFormat.format(todayDate); // 域名訪問的相對路徑(經過瀏覽器訪問的連接-虛擬路徑) String saveToPath = accessPath + today + "/"; // 真實路徑,實際儲存的路徑 String realPath = realBasePath + today + "/"; // 儲存文件的物理路徑,使用本地路徑儲存 String filepath = realPath + fileName; logger.info("上傳圖片名爲:" + fileName+"--虛擬文件路徑爲:" + saveToPath +"--物理文件路徑爲:" + realPath); // 判斷有沒有對應的文件夾 File destFile = new File(filepath); if (!destFile.getParentFile().exists()) { destFile.getParentFile().mkdirs(); } // 輸出流 輸出到文件 OutputStream outputStream = new FileOutputStream(destFile); // 緩衝區 byte[] bs = new byte[1024]; int len = -1; while ((len = inputStream.read(bs)) != -1) { outputStream.write(bs,0,len); } inputStream.close(); outputStream.close(); // 返回虛擬路徑,給連接訪問 return saveToPath+fileName; } }
application.properties:app
# 上傳的服務器上的映射文件夾
file.accessPath=/uploadimg/
#靜態資源對外暴露的訪問路徑
file.staticAccessPath=/uploadimg/**
#文件上傳目錄(注意Linux和Windows上的目錄結構不一樣)
#file.uploadFolder=/root/uploadFiles/
file.uploadFolder=C://File_rec/tmp/
關鍵的配置類:dom
package com.hj.blog.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * 設置虛擬路徑,訪問絕對路徑下資源 */ @Configuration public class UploadConfig implements WebMvcConfigurer{ @Value("${file.staticAccessPath}") private String staticAccessPath; @Value("${file.uploadFolder}") private String uploadFolder; @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(staticAccessPath).addResourceLocations("file:" + uploadFolder); } }
經過最後的配置類,設置了虛擬的路徑到物理的路徑中。也能夠正常的訪問圖片了。