SpringBoot實(shí)現(xiàn)本地文件存儲(chǔ)及預(yù)覽過(guò)程
一、前言
若使用本機(jī)存儲(chǔ)來(lái)存放文件資源
核心實(shí)現(xiàn)過(guò)程:
- 上傳文件,保存文件(本地磁盤(pán))
- 返回文件HTTP訪問(wèn)服務(wù)器路徑給前端,進(jìn)行效果展示
二、儲(chǔ)備
服務(wù)端接收上傳的目的是提供文件的訪問(wèn)服務(wù),對(duì)于SpringBoot而言,其對(duì)靜態(tài)資源訪問(wèn)提供了很好的支持,使用其提供的基本默認(rèn)配置可以滿足開(kāi)發(fā)需求,同時(shí),又支持開(kāi)發(fā)人員進(jìn)行自定義配置。
SpringBoot默認(rèn)將 / 所有訪問(wèn)映射到一下目錄:**
classpath:/META-INF/resources
classpath:/static
classpath:/public
classpath:/resources
在src/main/resources下新建pubic、resources、static三個(gè)文件夾,分別放入x.png、xx.png、xxx.png三張圖片
如下:
啟動(dòng)項(xiàng)目后,分別訪問(wèn):
http://localhost:9999/x.png
http://localhost:9999/xx.png
http://localhost:9999/xxx.png
正常返回圖片資源。
說(shuō)明,SpringBoot默認(rèn)會(huì)挨個(gè)從pubic、resources、static里面找是否存在相應(yīng)的資源,如果有則直接返回。
可以看出這里的靜態(tài)資源都在classpath下。
那么就出現(xiàn)問(wèn)題:
- 應(yīng)用的文件資源不能和項(xiàng)目代碼分開(kāi)存儲(chǔ)
- 項(xiàng)目打包困難,當(dāng)上傳的文件越來(lái)越多,項(xiàng)目的打包jar越來(lái)越大
- 代碼與文件數(shù)據(jù)不能分開(kāi)存儲(chǔ),就意味著文件數(shù)據(jù)的備份將變得復(fù)雜
三、方案
SpringBoot為我們提供了 spring.resources.static-locations 配置自定義靜態(tài)文件的位置:
spring: web: resources: static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${demo.web.upload-path} demo: web: upload-path: D:/data/
- 配置 demo.web.upload-path 為與項(xiàng)目代碼分離的靜態(tài)資源路徑,即:文件上傳保存根路徑
- 配置 spring.web.resources.static-locations 除了帶上SpringBoot默認(rèn)的靜態(tài)資源路徑之外,加上file:${demo.web.upload-path}指向外部的文件資源上傳路徑,即:該路徑下的靜態(tài)資源可以直接對(duì)外提供HTTP訪問(wèn)服務(wù)
四、Java Code
public String upload(MultipartFile file, HttpServletRequest request) { if (file == null) { throw new BizException("參數(shù)為空"); } // 在 uploadPath 文件夾中通過(guò)日期對(duì)上傳的文件歸類保存 // 例如:/2022/02/22/df9a66f1-760b-4f95-9faf-b5a216966718.png String format = sdf.format(new Date()); File folder = new File(uploadPath + format); if (!folder.isDirectory()) { folder.mkdirs(); } // 對(duì)上傳的文件重命名, 避免文件重名 String oldName = file.getOriginalFilename(); String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."), oldName.length()); try { // 文件保存 file.transferTo(new File(folder, newName)); // 返回上傳文件的訪問(wèn)路徑 // 例如:http://localhost:9999/2022/02/22/df9a66f1-760b-4f95-9faf-b5a216966718.png String filePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/" + format + newName; return filePath; } catch (IOException e) { throw new BizException("系統(tǒng)錯(cuò)誤"); } }
五、模擬文件
將此 upload.html 文件放到 classpath:public 目錄下,對(duì)外提供訪問(wèn)。
如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/upload" method="post" enctype="multipart/form-data"> <input type="file" name="uploadFile" value="請(qǐng)選擇上傳文件"> <input type="submit" value="保存"> </form> </body> </html>
訪問(wèn)測(cè)試,點(diǎn)擊"選擇文件",之后"保存":
文件被保存到服務(wù)端的 demo.web.upload-path 指定的資源目錄下
瀏覽器端響應(yīng)結(jié)果如下,返回一個(gè)文件HTTP訪問(wèn)路徑:
http://localhost:9999/2022/02/22/df9a66f1-760b-4f95-9faf-b5a216966718.png
使用該HTTP訪問(wèn)路徑,在瀏覽器端訪問(wèn)效果如下。
證明我們的文件已經(jīng)成功上傳到服務(wù)端,以后需要訪問(wèn)該圖片就通過(guò)這個(gè)HTTP URL就可以了?。?!
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java中的ReentrantReadWriteLock使用詳解
這篇文章主要介紹了Java中的ReentrantReadWriteLock使用詳解,ReentrantReadWriteLock是Java中的一個(gè)鎖實(shí)現(xiàn),它提供了讀寫(xiě)分離的功能,這種讀寫(xiě)分離的機(jī)制可以提高并發(fā)性能,特別適用于讀多寫(xiě)少的場(chǎng)景,需要的朋友可以參考下2023-11-11透明化Sharding-JDBC數(shù)據(jù)庫(kù)字段加解密方案
這篇文章主要為大家介紹了透明化Sharding-JDBC數(shù)據(jù)庫(kù)字段加解密方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-02-02Java基礎(chǔ)學(xué)習(xí)筆記之?dāng)?shù)組詳解
這篇文章主要介紹了Java基礎(chǔ)學(xué)習(xí)筆記之?dāng)?shù)組,結(jié)合實(shí)例形式詳細(xì)分析了java的基本概念、定義、迭代、輸出、反轉(zhuǎn)、排序等常用操作技巧,需要的朋友可以參考下2019-08-08Spring @ExceptionHandler注解統(tǒng)一異常處理和獲取方法名
這篇文章主要介紹了Spring注解之@ExceptionHandler 統(tǒng)一異常處理和獲取方法名,在實(shí)際項(xiàng)目中,合理使用@ExceptionHandler能夠提高代碼的可維護(hù)性和用戶體驗(yàn),通過(guò)本文的解析和實(shí)踐,讀者可以更好地理解和掌握@ExceptionHandler的用法和原理2023-09-09Java語(yǔ)言實(shí)現(xiàn)最大堆代碼示例
這篇文章主要介紹了Java語(yǔ)言實(shí)現(xiàn)最大堆代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-12-12java實(shí)現(xiàn)基于TCP協(xié)議網(wǎng)絡(luò)socket編程(C/S通信)
這篇文章主要介紹了java實(shí)現(xiàn)基于TCP協(xié)議網(wǎng)絡(luò)socket編程(C/S通信),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10emoji表情與unicode編碼互轉(zhuǎn)的實(shí)現(xiàn)(JS,JAVA,C#)
這篇文章主要介紹了emoji表情與unicode編碼互轉(zhuǎn)的實(shí)現(xiàn)(JS,JAVA,C#),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01