1. 程式人生 > 其它 >spingboot圖片檔案上傳,訪問(艱難,踩了很多坑!都是淚)

spingboot圖片檔案上傳,訪問(艱難,踩了很多坑!都是淚)

總體需求:前端上傳的檔案或者視訊是base64格式的,我需要取到它,轉換成指定格式的圖片或者視訊,然後儲存到本地磁碟(E:/upload/),並且將儲存的路徑存到資料庫內,並且根據這個路徑,返回給前端。

來,開整!

1:首先寫個檔案上傳,儲存在本地磁碟的方法(base64資料要先去掉頭,才能轉換成圖片或者視訊檔案。並且前端傳過來的base64到後端,會把資料中的+號,替換成空,所以轉換的時候要替換回來,就是下圖紅色部分

  我這個專案的需要是安裝日期儲存圖片,下面方法也寫的有。這個方法返回的是一個url,存到資料庫的

//上傳圖片
@PostMapping(value = "/api/fileUpload")
public String fileUpload(String myfileurl) throws FileNotFoundException {
String flag="0";
String dburl="";
String dataPrix = ""; //base64格式前頭
String data = "";//實體部分資料
if(myfileurl==null||"".equals(myfileurl)){
return flag;
} else {
String [] d = myfileurl.split("base64,");//將字串分成陣列
if(d != null && d.length == 2){
dataPrix = d[0];
data = d[1];
}else {
return flag;
}
}
data=data.replaceAll(" ","+");

String suffix = "";//圖片字尾,用以識別哪種格式資料
//data:image/jpeg;base64,base64編碼的jpeg圖片資料
if("data:image/jpeg;".equalsIgnoreCase(dataPrix)){
suffix = ".jpg";
}else if("data:image/x-icon;".equalsIgnoreCase(dataPrix)){
//data:image/x-icon;base64,base64編碼的icon圖片資料
suffix = ".ico";
}else if("data:image/gif;".equalsIgnoreCase(dataPrix)){
//data:image/gif;base64,base64編碼的gif圖片資料
suffix = ".gif";
}else if("data:image/png;".equalsIgnoreCase(dataPrix)){
//data:image/png;base64,base64編碼的png圖片資料
suffix = ".png";
}else if("data:image/wedp;".equalsIgnoreCase(dataPrix)){
//data:image/png;base64,base64編碼的png圖片資料
suffix = ".wedp";
}else if("data:video/mp4;".equalsIgnoreCase(dataPrix)){
//data:image/png;base64,base64編碼的png圖片資料
suffix = ".mp4";
}else {
return flag;
}
//獲取隨機數給檔案命名
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
String tempFileName=uuid+suffix;
//建立年月日資料夾
Date date = new Date();
String dataForm = new SimpleDateFormat("yyyy-MM-dd").format(date);
String imgFilePath = "E:/upload/"+dataForm+"/";//
//如果不存在,建立資料夾
File f = new File(imgFilePath);
if(!f.exists()) {
f.mkdirs();
}
BASE64Decoder decoder = new BASE64Decoder();
try {
//Base64解碼
byte[] b = decoder.decodeBuffer(data);
for(int i=0;i<b.length;++i) {
if(b[i]<0) {
//調整異常資料
b[i]+=256;
}
}
OutputStream out = new FileOutputStream(imgFilePath+tempFileName);
out.write(b);
out.flush();
out.close();
dburl =imgFilePath+tempFileName;
dburl = dburl.replace("E:","");
return dburl;
} catch (IOException e) {
e.printStackTrace();
return flag;
}

}

2.寫一個上傳並且儲存url到資料庫的方法
//儲存巡檢業務附件
@ResponseBody
@PostMapping(value = "/api/addInspectFile")
public int addInspectFile(String myfileurl) throws FileNotFoundException {
String fileUrl =fileController.fileUpload(myfileurl);
int productFileAutoid=0;
if("0".equals(fileUrl)){
return productFileAutoid;
}else {
//檔案上傳成功後,插入product_file 附件表
productFileAutoid =productFileService.addInspectFile(fileUrl);

}
return productFileAutoid;
}

3.最重要的一步,也是最坑得我最狠的一步(配置靜態虛擬路徑對映儲存圖片的磁碟路徑或者雲伺服器路徑
),這個配置其實就是為了前端訪問的時候,給它一個虛擬的地址,來對映你的實際位置或者伺服器存放的地址

首先,你先確定你的專案是不是自己動手寫的,還是從網上下載的一個成熟專案。
如果全都是你自己寫的,OK,沒問題,有兩種方法可以選擇
(1):配置application.yml檔案
resources:
static-locations: classpath:/templates/,classpath:/static/,classpath:/resources,classpath:/META-INF/resources,file:E://upload/
profiles:
active:
mvc:
static-path-pattern: /static/**,/upload/**

(2):自己寫個配置類
/**
* 資源對映路徑
*/
@CrossOrigin
@Configuration
public class MyWebAppConfigurer extends WebMvcConfigurationSupport {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/**
* 資源對映路徑
* addResourceHandler:訪問對映路徑
* addResourceLocations:資源絕對路徑
*/
registry.addResourceHandler("/upload/**").addResourceLocations("file:E://upload/");
super.addResourceHandlers(registry);
}
}

如果你是自己從網上下的一個專案,首先要檢查一下以前是否有沒有配置虛擬路徑,一般是配置過。我就是卡在這裡好幾天,自己傻傻的寫了個配置,其實專案裡面就有。直接全域性搜尋
registry.addResourceHandler("/upload/**").addResourceLocations("file:E://upload/");  這兩個方法,如果其他檔案裡有,就是配置了的,直接在後面加一個一條記錄就可以了!!!!
不需要在自己寫配置類了!!!到時候也會不生效!切記!

本地測試一下,可以訪問

一切OK!

然後把這個url給到前端,前端直接用src = 就可以引用了!!!!!