如何在springboot項目中使用minio上傳下載刪除文件

引入maven依賴

<!--  minio   -->
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.2.2</version>
</dependency>

申請 bucket | access_key | secret_key

項目中配置相關參數

    minio:# access_keyaccessKey: xxxxxx# secret_keysecretKey: xxxxxx# bucketbucketName: bucket1# 內網地址endpoint: http://127.0.0.1:9000# 外網地址website: https://xxx.xxx.cn:9000# 自定義文件大小限制 注:要與spring.servlet.multipart.max-file-size | max-request-size 區分開maxFileSize:img: 10video: 30

endpoint | website | maxFileSize 可根據項目需要增刪,后面不再贅述。

Minio 配置信息


/*** Minio 配置信息** @author ruoyi*/
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig
{/*** 用戶名*/private String accessKey;/*** 密碼*/private String secretKey;/*** 存儲桶名稱*/private String bucketName;/*** 服務地址*/private String endpoint;/*** 公網*/private String webSite;/*** 文件大小限制*/private MediaMaxFileSize maxFileSize;public static class MediaMaxFileSize{private Long img;private Long video;public Long getImg() {return img;}public void setImg(Long img) {this.img = img;}public Long getVideo() {return video;}public void setVideo(Long video) {this.video = video;}}public String getWebSite() {return webSite;}public void setWebSite(String webSite) {this.webSite = webSite;}public MediaMaxFileSize getMaxFileSize() {return maxFileSize;}public void setMaxFileSize(MediaMaxFileSize maxFileSize) {this.maxFileSize = maxFileSize;}public String getAccessKey() {return accessKey;}public void setAccessKey(String accessKey) {this.accessKey = accessKey;}public String getSecretKey() {return secretKey;}public void setSecretKey(String secretKey) {this.secretKey = secretKey;}public String getBucketName() {return bucketName;}public void setBucketName(String bucketName) {this.bucketName = bucketName;}public String getEndpoint() {return endpoint;}public void setEndpoint(String endpoint) {this.endpoint = endpoint;}@Beanpublic MinioClient getMinioClient() {return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();}
}

/*** 文件對象實體類*/
public class MinioFile implements Serializable {// 文件服務器文件所屬組private String bucketName;// 不帶文件組的文件URLprivate String path;// 帶文件組的文件URLprivate String fullPath;// 站點信息private String webSite;// 帶站點的文件URLprivate String webUrl;// 原始文件名private String fileName;// 內網廉價而private String intranetWebSite;// 內網地址private String intranetWebUrl;// 其他參數private Map<String, Object> params = new HashMap<>();public String getFullPath() {return fullPath;}public void setFullPath(String fullPath) {this.fullPath = fullPath;}public String getPath() {return path;}public void setPath(String path) {this.path = path;}public String getWebSite() {return webSite;}public void setWebSite(String webSite) {this.webSite = webSite;}public String getWebUrl() {return webUrl;}public void setWebUrl(String webUrl) {this.webUrl = webUrl;}public String getFileName() {return fileName;}public void setFileName(String fileName) {this.fileName = fileName;}public String getIntranetWebUrl() {return intranetWebUrl;}public void setIntranetWebUrl(String intranetWebUrl) {this.intranetWebUrl = intranetWebUrl;}public String getIntranetWebSite() {return intranetWebSite;}public void setIntranetWebSite(String intranetWebSite) {this.intranetWebSite = intranetWebSite;}public String getBucketName() {return bucketName;}public void setBucketName(String bucketName) {this.bucketName = bucketName;}public Map<String, Object> getParams() {if (params == null) {params = new HashMap<>();}return params;}public void setParams(Map<String, Object> params) {this.params = params;}public Object getParam(String key) {if (params == null) {params = new HashMap<>();return null;}return params.get(key);}public void putParam(String key, Object value) {if (params == null) {params = new HashMap<>();}params.put(key, value);}}

文件上傳下載刪除工具類封裝

項目基于RuoYi開源框架搭建,因此此處工具類引入開源框架中一些內置工具類


import com.ruoyi.common.exception.file.InvalidExtensionException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.MimeTypeUtils;
import com.ruoyi.common.utils.uuid.Seq;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import io.minio.http.Method;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.io.InputStream;
import java.util.Date;/*** Minio 文件存儲工具類* * @author ruoyi*/
@Component
public class MinioUtil
{private static Logger log = LoggerFactory.getLogger(MinioUtil.class);/*** minio實例*/private static MinioClient minioClient;/*** minio配置類*/private static MinioConfig minioConfig;@Autowiredpublic void setMinioUtil(MinioClient minioClient, MinioConfig minioConfig){MinioUtil.minioClient = minioClient;MinioUtil.minioConfig = minioConfig;}public MinioFile uploadFile(MultipartFile file, String fileType, String filePurpose) throws InvalidExtensionException, IOException {if("01".equals(fileType)){FileUploadUtils.assertAllowed(file, MimeTypeUtils.IMAGE_EXTENSION_10001, minioConfig.getMaxFileSize().getImg() * 1024 * 1024);} else if ("02".equals(fileType)) {FileUploadUtils.assertAllowed(file, MimeTypeUtils.VIDEO_EXTENSION_10002, minioConfig.getMaxFileSize().getVideo() * 1024 * 1024);}// 年月String yyyyMM = DateUtils.parseDateToStr("yyyyMM", new Date());// 文件名 moduleName/業務類型/文件類型/年月/Seq隨機字符/文件后綴String fileName = StringUtils.format("{}/{}/{}/{}/{}.{}","moduleName", getFilePurpose(filePurpose)// 使用用途, getFileType(fileType)//文件類型, yyyyMM, Seq.getId(), FileUploadUtils.getExtension(file));return uploadFile(file, fileName);}private MinioFile uploadFile(MultipartFile file, String fileName) throws IOException {String webUrl = uploadFile(minioConfig.getBucketName(), fileName, file);MinioFile minioFile = new MinioFile();minioFile.setBucketName(minioConfig.getBucketName());minioFile.setPath(fileName);minioFile.setFullPath(StringUtils.format("{}/{}",minioConfig.getBucketName(),fileName));minioFile.setWebSite(minioConfig.getWebSite());minioFile.setWebUrl(webUrl.replace(minioConfig.getEndpoint(),minioConfig.getWebSite()));minioFile.setFileName(file.getOriginalFilename());minioFile.setIntranetWebSite(minioConfig.getEndpoint());minioFile.setIntranetWebUrl(webUrl);return minioFile;}/*** 上傳文件* * @param bucketName 桶名稱* @param fileName* @throws IOException*/private String uploadFile(String bucketName, String fileName, MultipartFile multipartFile) throws IOException{String url = "";try (InputStream inputStream = multipartFile.getInputStream()){minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(inputStream, multipartFile.getSize(), -1).contentType(multipartFile.getContentType()).build());url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(fileName).method(Method.GET).build());url = url.substring(0, url.indexOf('?'));return ServletUtils.urlDecode(url);}catch (Exception e){throw new IOException(e.getMessage(), e);}}/*** 刪除文件* @param fileName*/public void removeFile(String fileName){try{minioClient.removeObject(RemoveObjectArgs.builder().bucket(minioConfig.getBucketName()).object(fileName).build());}catch (Exception e){e.printStackTrace();log.error("MinioUtil-uploadMinio-error", e);}}/*** 文件類型 可自定義* @param fileType* @return*/private String getFileType(String fileType){String fileTypeName = null;switch (fileType){case "01":fileTypeName = "image";break;case "02":fileTypeName = "video";break;default:fileTypeName = "undefined";}return fileTypeName;}/*** 獲取文件使用用途 可自定義* @param filePurpose* @return*/private String getFilePurpose(String filePurpose){String filePurposeType = null;switch (filePurpose){case "01":filePurposeType = "banner";break;default:filePurposeType = "undefined";}return filePurposeType;}}

MimeTypeUtils.IMAGE_EXTENSION_10001 和 MimeTypeUtils.VIDEO_EXTENSION_10002為在原框架工具類上新增自定義文件后綴
另根據業務需要,對框架FileUploadUtils中的assertAllowed進行方法重載

/*** 文件大小校驗** @param file 上傳的文件* @return* @throws FileSizeLimitExceededException 如果超出最大大小* @throws InvalidExtensionException*/public static final void assertAllowed(MultipartFile file, String[] allowedExtension)throws FileSizeLimitExceededException, InvalidExtensionException{assertAllowed(file, allowedExtension, DEFAULT_MAX_SIZE);}/*** 文件大小校驗** @param file 上傳的文件* @param maxSize 最大限制* @return* @throws FileSizeLimitExceededException 如果超出最大大小* @throws InvalidExtensionException*/public static final void assertAllowed(MultipartFile file, String[] allowedExtension, long maxSize)throws FileSizeLimitExceededException, InvalidExtensionException{long size = file.getSize();if (size > maxSize){throw new FileSizeLimitExceededException(maxSize / 1024 / 1024);}String fileName = file.getOriginalFilename();String extension = getExtension(file);if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)){if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION){throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,fileName);}else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION){throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,fileName);}else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION){throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,fileName);}else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION){throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,fileName);}else if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION_10001){throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,fileName);}else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION_10002){throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,fileName);}else{throw new InvalidExtensionException(allowedExtension, extension, fileName);}}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/166805.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/166805.shtml
英文地址,請注明出處:http://en.pswp.cn/news/166805.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ROLLUP 的幾點說明(十七)

ROLLUP 最根本的作用是提高某些查詢的查詢效率&#xff08;無論是通過聚合來減少數據量&#xff0c;還是修改列順序以匹配前綴索引&#xff09;。因此 ROLLUP 的含義已經超出了“上卷”的范圍。這也是為什么在源代碼中&#xff0c;將其命名為 Materialized Index&#xff08;物…

土壤教學經典用圖30張

一、土壤分布 二、土壤形成與氣候 三、土壤形成與地形 四、土壤形成與成土母質 五、成土過程示意圖 六、土壤剖面實景圖 七、土壤剖面示意圖 八、土壤質地 以上圖片多來源于 人教、湘教、魯教、中圖、滬教 五套新教材及地圖冊

忘記7-zip密碼,如何解壓文件?

7z壓縮包設置了密碼&#xff0c;解壓的時候就需要輸入正確對密碼才能順利解壓出文件&#xff0c;正常當我們解壓文件或者刪除密碼的時候&#xff0c;雖然方法多&#xff0c;但是都需要輸入正確的密碼才能完成。忘記密碼就無法進行操作。 那么&#xff0c;忘記了7z壓縮包的密碼…

華為云測試計劃CodeArts TestPlan常見問答匯總

1.【TestPlan】測試用例界面操作歷史&#xff0c;能記錄哪些操作 答&#xff1a;除了附件上傳、更新、用例評論沒有記錄的&#xff0c;其他測試用例詳情內的所有內容&#xff0c;比如描述、條件、測試步驟修改都有記錄&#xff1b; 2.【TestPlan】測試用例等級選擇規則是什么&…

YOLOv3老矣尚能戰否?基于YOLOv3開發構建建鋼鐵產業產品智能自動化檢測識別系統,我們來與YOLOv5進行全方位對比評測

鋼鐵產業產品智能自動化檢測識別相關的項目在我們前面的博文中已經有了相應的實踐了&#xff0c;感興趣的話可以自行移步閱讀即可&#xff1a;《python基于DETR(DEtection TRansformer)開發構建鋼鐵產業產品智能自動化檢測識別系統》 《AI助力鋼鐵產業數字化&#xff0c;pytho…

計算兩個經緯度之間的真是距離----c++

來源:https://www.open-open.com/lib/view/open1430573897802.html #include <cmath> #define EARTH_RADIUS 6371.0;// 地球半徑&#xff0c;單位千米static double HaverSin(double theta) {double v sin(theta / 2);return v * v; }static double ConvertDegreesToR…

OPPO VOOC快充原理

1 USB 3.0標準A插頭 USB 3.0連接器是基于USB 2.0改進而來的&#xff0c;這個設計給USB 3.0連接器帶來了一些潛在風險&#xff0c;如果USB 3.0設備插入主機的速度太慢&#xff0c;3.0的針腳還沒來得及被識別到&#xff0c;就會被主機判定成USB 2.0的設備。 Figure 1-1 USB 3.0標…

centos系統下,docker安裝sqlserver并用本地Navicat連接

文章目錄 一&#xff0c;centos下安裝docker二&#xff0c;docker安裝sqlserver20192.1 安裝遇到的問題2.1.1 修改用戶名進不去數據庫2.1.2 安裝2022版的sqlserver發現啟動失敗 三&#xff0c;Navicat連接centos下的sqlserver3.1 下載ODBC Driver 參考微軟網址&#xff1a; 使…

代碼隨想錄算法訓練營第四十五天【動態規劃part07】 | 70. 爬樓梯 (進階)、322. 零錢兌換、279.完全平方數

70. 爬樓梯 &#xff08;進階&#xff09; 題目鏈接&#xff1a; 題目頁面 求解思路&#xff1a; 動規五部曲 確定dp數組及其下標含義&#xff1a;爬到有i階樓梯的樓頂&#xff0c;有dp[i]種方法遞推公式&#xff1a;dp[i] dp[i-j];dp數組的初始化&#xff1a;dp[0] 1;確…

EcuM介紹

ECUM 1. ECUM 主要需求2. EcuM 設計詳情2.1 啟動與下電休眠2.1.1 啟動與初始化2.1.2 EcuM 下電/休眠2.2 喚醒事件管理2.3 ECUM 模式2.3.1 Flexible2.3.2 Fixed2.3.3 Startup2.3.4 Shutdown2.3.5 SLEEP PHASE: Poll or Halt3. EcuM 集成接口調用4. 名稱縮寫解釋5. 參考文檔1. EC…

數據治理技術之數據清洗

數據清洗背景 數據質量一般由準確性、完整性、一致性、時效性、可信性以及可解釋性等特征來描述&#xff0c;根據 Rahm 等人在 2000 年對數據質量基于單數據源還是多數據源以及問題出在模式層還是實例層的標準進行分類&#xff0c;將數據質量問題分為單數據源模式層問題、單數…

虛幻學習筆記—給UI添加動畫

一、前言 本文所使用的虛幻版本為5.3.2&#xff0c;之前工作都是用unity&#xff0c;做這類效果用的最多的是一個DoTween的插件&#xff0c;在虛幻中都內置集成了這這種效果制作。 圖1.1 UI動畫 二、過程 1、首先&#xff0c;在諸如按鈕、圖像等可交互控件中選中&#xff0c;如…

centos userad命令詳解

命令作用 用于創建用戶常見參數 -d 指定用戶的家目錄-e 賬號的到期時間&#xff0c;格式YYYY-MM-DD-u 指定該用戶的默認UID&#xff0c;&#xff08;centos7開始1000是普通用戶的第一個UID&#xff09;-g 指定一個初始的用戶基本組&#xff08;必須已經存在&#xff09;-G 指定…

計算機網絡之運輸層

一、概述 物理層、數據鏈路層以及網絡層它們共同解決了將主機通過異構網絡互聯起來所面臨的的問題&#xff0c;實現了主機到主機的通信 但實際上在計算機網絡中進行通信的真正實體是位于通信兩端主機中的進程 如何為運行在不同主機上的應用進程提供直接的通信服務時運輸層的任務…

基于Boost.Asio實現端口映射器

Boost.Asio 是一個功能強大的 C 庫&#xff0c;用于異步編程和網絡編程&#xff0c;它提供了跨平臺的異步 I/O 操作。在這篇文章中&#xff0c;我們將深入分析一個使用 Boost.Asio 實現的簡單端口映射服務器&#xff0c;該服務器能夠將本地端口的數據包轉發到指定的遠程服務器上…

從設計上理解JDK動態代理

作者簡介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中興通訊、美團架構師&#xff0c;現某互聯網公司CTO 聯系qq&#xff1a;184480602&#xff0c;加我進群&#xff0c;大家一起學習&#xff0c;一起進步&#xff0c;一起對抗互聯網寒冬 照理說&#xff0c;動態…

上門預約小程序開發優勢

想要放松身心&#xff0c;享受按摩的舒適感&#xff1f;那就需要一個專業的按摩師來上門服務。我們開發的預約按摩小程序app系統&#xff0c;匯聚各類上門按摩服務&#xff0c;包括推拿SPA、小兒推拿、中醫等&#xff0c;為您提供高價值、高標準的養生健康體驗。24小時隨時提供…

GEE土地分類——使用隨機森林方法和多源遙感數據進行面向對象的土地分類NAIP數據為例

簡介: 數據: 國家農業圖像計劃 (NAIP) 在美國大陸的農業生長季節獲取航空圖像。 NAIP 項目每年根據可用資金和圖像獲取周期簽訂合同。從 2003 年開始,NAIP 以 5 年為一個周期。2008 年是過渡年,2009 年開始采用 3 年周期。 NAIP 圖像以一米的地面采樣距離 (GSD) 采集,水…

【前端】讓列表像Excel單元格一樣編輯

前言 領導說了一堆的話,最后總結一句就是客戶很懶,客戶的員工更加懶。 本著讓別人節省時間的原則,提倡出了讓列表和Excal的單元格一樣,不僅看數據還可以隨時更改數據。 查資料 根據 Jeecg-Vue3 源碼介紹,從而知道是基于 Vben Admin 開源項目進行改造的。 因此在 Vben…

Sulfo-CY3 NHS熒光染料的制備和表征

Sulfo-CY3 NHS(源自星戈瑞的花菁染料)熒光染料的制備和表征是確保染料質量和性能的關鍵步驟。制備Sulfo-CY3 NHS熒光染料&#xff1a; 原材料準備&#xff1a;準備所需的原材料&#xff0c;包括CY3 NHS ester&#xff08;或等效的前體&#xff09;&#xff0c;用于制備Sulfo-C…