Springboot整合Minio對象存儲超級詳細講解以及配置搭建

windows環境下搭建minio步驟

1.從minio官網進行查看詳細信息

	地址:https://min.io/里面有詳細的配置信息搭建成功之后如下如所示:用戶名密碼默認情況下為 username:minioadmin password:minioadmin

在這里插入圖片描述

2.搭建成功之后的訪問

	地址:服務ip 端口9000http//127.0.0.1:9000 用戶名密碼為默認:minioadmin 創建桶時候要注意桶的名稱

在這里插入圖片描述

springboot整合和minio的步驟如下

1.pom坐標的指定

<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.2.2</version></dependency><!-- Hutool --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.18</version></dependency>

2.配置文件的設置如下

package com.java.javamethod.conf;import io.minio.MinioClient;
import lombok.SneakyThrows;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.annotation.Resource;/*** Minio配置類* @Author ww* @Date 2024/5/21 10:06* @Version 1.0*/@Configuration
@EnableConfigurationProperties(MinioProperties.class)
@ConditionalOnProperty(value = "oss.name", havingValue = "minio")
public class MinioConfiguration {@Resourceprivate MinioProperties ossProperties;@Bean@SneakyThrowspublic MinioClient minioClient() {return MinioClient.builder().endpoint(ossProperties.getEndpoint()).credentials(ossProperties.getAccessKey(), ossProperties.getSecretKey()).build();}}
package com.java.javamethod.conf;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;/*** @Author ww* @Date 2024/5/21 10:08* @Version 1.0*/
@Data
@ConfigurationProperties(prefix = MinioProperties.PREFIX)
public class MinioProperties {/*** 配置前綴*/public static final String PREFIX = "oss";/*** 對象存儲名稱*/private String name;/*** 對象存儲服務的URL*/private String endpoint;/*** Access key 賬戶ID*/private String accessKey;/*** Secret key 密碼*/private String secretKey;/*** 默認的存儲桶名稱*/private String bucketName = "qditwei";/*** 可上傳的文件后綴名*/private List<String> fileExt;}

3.minio工具類的封裝

package com.java.javamethod.service;import com.java.javamethod.domain.OssFile;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.List;/*** @Author ww* @Date 2024/5/21 10:54* @Version 1.0*/
public interface OssTemplate {/*** 存儲桶是否存在** @param bucketName 存儲桶名稱* @return boolean*/boolean bucketExists(String bucketName);/*** 獲取文件信息** @param fileName 存儲桶文件名稱* @return InputStream*/OssFile getOssInfo(String fileName);/*** 上傳文件** @param folderName 上傳的文件夾名稱* @param fileName   上傳文件名* @param file       上傳文件類* @return BladeFile*/OssFile upLoadFile(String folderName, String fileName, MultipartFile file);/*** 上傳文件** @param folderName 上傳的文件夾名稱* @param fileName   存儲桶對象名稱* @param suffix     文件后綴名* @param stream     文件流* @return BladeFile*/OssFile upLoadFile(String folderName, String fileName, String suffix, InputStream stream);/*** 刪除文件** @param fileName 存儲桶對象名稱*/boolean removeFile(String fileName);/*** 批量刪除文件** @param fileNames 存儲桶對象名稱集合*/boolean removeFiles(List<String> fileNames);/*** @Description: 下載文件* @Param response: 響應* @Param fileName: 文件名* @Param filePath: 文件路徑* @return: void*/void downloadFile(HttpServletResponse response, String fileName, String filePath);
}package com.java.javamethod.util;import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.ObjectUtil;
import com.java.javamethod.conf.MinioProperties;
import com.java.javamethod.domain.OssFile;
import com.java.javamethod.service.OssTemplate;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.DeleteObject;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.stream.Stream;/*** @Author ww* @Date 2024/5/21 10:52* @Version 1.0*/@Slf4j
@Service
public class MinioTemplate implements OssTemplate {/*** MinIO客戶端*/@Resourceprivate MinioClient client;/*** 配置類*/@Resourceprivate MinioProperties ossProperties;/*** 格式化時間*/private static final String DATE_FORMAT = "yyyyMMdd";/*** 字符集*/private static final String ENCODING = "UTF-8";/*** 存儲桶是否存在** @param bucketName 存儲桶名稱* @return boolean*/@Overridepublic boolean bucketExists(String bucketName) {try {return client.bucketExists(BucketExistsArgs.builder().bucket(getBucketName(bucketName)).build());} catch (Exception e) {log.error("minio bucketExists Exception:{}", e);}return false;}/*** @Description: 創建 存儲桶* @Param bucketName: 存儲桶名稱*/public void makeBucket(String bucketName) {try {if (!client.bucketExists(BucketExistsArgs.builder().bucket(getBucketName(bucketName)).build())) {client.makeBucket(MakeBucketArgs.builder().bucket(getBucketName(bucketName)).build());log.info("minio makeBucket success bucketName:{}", bucketName);}} catch (Exception e) {log.error("minio makeBucket Exception:{}", e);}}/*** 獲取文件信息** @param fileName 存儲桶文件名稱* @return InputStream*/@Overridepublic OssFile getOssInfo(String fileName) {try {StatObjectResponse stat = client.statObject(StatObjectArgs.builder().bucket(getBucketName(ossProperties.getBucketName())).object(fileName).build());OssFile ossFile = new OssFile();ossFile.setName(ObjectUtil.isEmpty(stat.object()) ? fileName : stat.object());ossFile.setFilePath(ossFile.getName());ossFile.setDomain(getOssHost(ossProperties.getBucketName()));ossFile.setHash(String.valueOf(stat.hashCode()));ossFile.setSize(stat.size());ossFile.setPutTime(DateUtil.date(stat.lastModified().toLocalDateTime()));ossFile.setContentType(stat.contentType());return ossFile;} catch (Exception e) {log.error("minio getOssInfo Exception:{}", e);}return null;}/*** 上傳文件** @param folderName 上傳的文件夾名稱* @param fileName   上傳文件名* @param file       上傳文件類* @return BladeFile*/@Override@SneakyThrowspublic OssFile upLoadFile(String folderName, String fileName, MultipartFile file) throws RuntimeException {if (file == null || file.isEmpty()) {throw new RuntimeException("文件不能為空");}// 文件大小if (file.getSize() > 5 * 1024 * 1024) {throw new RuntimeException("文件大小不能超過5M");}String suffix = getFileExtension(file.getOriginalFilename());// 文件后綴判斷/*if (!CollUtil.contains(ossProperties.getFileExt(), suffix)) {String error = String.format("文件類型錯誤,目前支持[%s]等文件類型",String.join(",", ossProperties.getFileExt()));throw new RuntimeException(error);}*/try {return upLoadFile(folderName, fileName, suffix, file.getInputStream());} catch (Exception e) {log.error("minio upLoadFile Exception:{}", e);throw new RuntimeException("文件上傳失敗,請重新上傳或聯系管理員");}}/*** 獲取文件后綴名** @param fullName 文件全名* @return {String}*/public static String getFileExtension(String fullName) {Assert.notNull(fullName, "minio file fullName is null.");String fileName = new File(fullName).getName();int dotIndex = fileName.lastIndexOf('.');return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1);}/*** 上傳文件** @param folderName 上傳的文件夾名稱* @param fileName   存儲桶對象名稱* @param suffix     文件后綴名* @param stream     文件流* @return BladeFile*/@Overridepublic OssFile upLoadFile(String folderName, String fileName, String suffix, InputStream stream) {try {return upLoadFile(ossProperties.getBucketName(), folderName, fileName, suffix, stream,"application/octet" + "-stream");} catch (Exception e) {log.error("minio upLoadFile Exception:{}", e);}return null;}/*** @Description: 上傳文件* @Param bucketName: 存儲桶名稱* @Param folderName: 上傳的文件夾名稱* @Param fileName: 上傳文件名* @Param suffix: 文件后綴名* @Param stream: 文件流* @Param contentType: 文件類型*/@SneakyThrowspublic OssFile upLoadFile(String bucketName, String folderName, String fileName, String suffix, InputStream stream,String contentType) {if (!bucketExists(bucketName)) {log.info("minio bucketName is not creat");makeBucket(bucketName);}OssFile file = new OssFile();String originalName = fileName;String filePath = getFilePath(folderName, fileName, suffix);client.putObject(PutObjectArgs.builder().bucket(getBucketName(bucketName)).object(filePath).stream(stream, stream.available(), -1).contentType(contentType).build());file.setOriginalName(originalName);file.setName(filePath);file.setDomain(getOssHost(bucketName));file.setFilePath(filePath);stream.close();log.info("minio upLoadFile success, filePath:{}", filePath);return file;}/*** 刪除文件** @param fileName 存儲桶對象名稱*/@Overridepublic boolean removeFile(String fileName) {try {client.removeObject(RemoveObjectArgs.builder().bucket(getBucketName(ossProperties.getBucketName())).object(fileName).build());log.info("minio removeFile success, fileName:{}", fileName);return true;} catch (Exception e) {log.error("minio removeFile fail, fileName:{}, Exception:{}", fileName, e);}return false;}/*** 批量刪除文件** @param fileNames 存儲桶對象名稱集合*/@Overridepublic boolean removeFiles(List<String> fileNames) {try {Stream<DeleteObject> stream = fileNames.stream().map(DeleteObject::new);client.removeObjects(RemoveObjectsArgs.builder().bucket(getBucketName(ossProperties.getBucketName())).objects(stream::iterator).build());log.info("minio removeFiles success, fileNames:{}", fileNames);return true;} catch (Exception e) {log.error("minio removeFiles fail, fileNames:{}, Exception:{}", fileNames, e);}return false;}/*** @Description: 下載文件* @Param response: 響應* @Param fileName: 文件名* @Param filePath: 文件路徑*/@Overridepublic void downloadFile(HttpServletResponse response, String fileName, String filePath) {GetObjectResponse is = null;try {GetObjectArgs getObjectArgs =GetObjectArgs.builder().bucket(ossProperties.getBucketName()).object(filePath).build();is = client.getObject(getObjectArgs);// 設置文件ContentType類型,這樣設置,會自動判斷下載文件類型response.setContentType("application/x-msdownload");response.setCharacterEncoding(ENCODING);// 設置文件頭:最后一個參數是設置下載的文件名并編碼為UTF-8response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, ENCODING));IoUtil.copy(is, response.getOutputStream());log.info("minio downloadFile success, filePath:{}", filePath);} catch (Exception e) {log.error("minio downloadFile Exception:{}", e);} finally {IoUtil.close(is);}}/*** 獲取文件外鏈** @param bucketName bucket名稱* @param fileName   文件名稱* @param expires    過期時間* @return url*/public String getPresignedObjectUrl(String bucketName, String fileName, Integer expires) {String link = "";try {link = client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(getBucketName(bucketName)).object(fileName).expiry(expires).build());} catch (Exception e) {log.error("minio getPresignedObjectUrl is fail, fileName:{}", fileName);}return link;}/*** 根據規則生成存儲桶名稱規則** @param bucketName 存儲桶名稱* @return String*/private String getBucketName(String bucketName) {return bucketName;}/*** 根據規則生成文件路徑** @param folderName       上傳的文件夾名稱* @param originalFilename 原始文件名* @param suffix           文件后綴名* @return string 上傳的文件夾名稱/yyyyMMdd/原始文件名_時間戳.文件后綴名*/private String getFilePath(String folderName, String originalFilename, String suffix) {return StrPool.SLASH + String.join(StrPool.SLASH, folderName, DateUtil.date().toString(DATE_FORMAT),originalFilename) + StrPool.C_UNDERLINE + DateUtil.current() + StrPool.DOT + suffix;}/*** 獲取域名** @param bucketName 存儲桶名稱* @return String*/public String getOssHost(String bucketName) {return ossProperties.getEndpoint() + StrPool.SLASH + getBucketName(bucketName);}}

4.swagger功能的驗證

package com.java.javamethod.controller;import com.java.javamethod.domain.OssFile;
import com.java.javamethod.util.MinioTemplate;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;/*** @Author ww* @Date 2024/5/21 10:23* @Version 1.0*/
@RestController
@Api(tags = "文件控制器", description = "文件管理控制器")
public class FileController {@ResourceMinioTemplate minioTemplate;@PostMapping("/upload")@ApiImplicitParams(value = {@ApiImplicitParam(name = "folderName", value = "文件路徑", required = true, dataType = "String"),@ApiImplicitParam(name = "fileName", value = "文件名", required = true, dataType = "String")})   // 注意seagger上傳文件時候一定要加@RequestPart否則可能沒法進行上傳文件public OssFile upload(String folderName, String fileName,@RequestPart MultipartFile file) {return minioTemplate.upLoadFile( folderName, fileName, file);}}

在這里插入圖片描述

在這里插入圖片描述

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

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

相關文章

python - 分割 pytest 的 conftest.py 文件

解決 pytest 的 conftest.py 文件過大問題。 1. 項目目錄結構 project_name ├── LICENSE ├── MANIFEST.in ├── Makefile ├── README.md ├── project_name │ ├── __init__.py │ ├── testing │ │ ├── __init__.py │ │ ├── fixtur…

vue項目實戰 - 如果高效的實現防抖和節流

在Vue項目中&#xff0c;處理高頻事件的優化至關重要&#xff0c;直接影響用戶體驗和應用性能。防抖&#xff08;Debounce&#xff09;和節流&#xff08;Throttle&#xff09;是兩種常用且有效的方法&#xff0c;可以控制事件觸發頻率&#xff0c;減少不必要的資源消耗。如何在…

SEO優化,小白程序員如何做SEO優化流量從0到1

原文鏈接&#xff1a;SEO優化&#xff0c;小白程序員如何做SEO優化流量從0到1 1、SEO是什么&#xff1f; SEO即&#xff1a;搜索引擎優化(Search Engine Optimization)&#xff0c;是一種通過優化網站結構、內容和外部鏈接等因素&#xff0c;提高網站在搜索引擎中的自然排名&…

python愛心樹表白代碼

以下是一個使用Python的turtle模塊來繪制一顆愛心并表白的簡單示例代碼&#xff1a; import turtle import math # 設置屏幕 screen turtle.Screen() screen.bgcolor("black") # 繪制愛心 def draw_heart(t, size): t.speed(9) t.penup() t.goto(0, -size…

Python Minio 工具類封裝

最近因為需要對大規模的文件進行存儲&#xff0c;選了多種對象存儲方案&#xff0c;最終選擇了MinIO&#xff0c;為了方便python的調用&#xff0c;在minio第三方包的基礎上進行進一步封裝調用&#xff0c;該工具除了基礎的功能外&#xff0c;還封裝了多線程分片下載文件和上傳…

DeepDriving | CUDA編程-03:線程層級

本文來源公眾號“DeepDriving”&#xff0c;僅用于學術分享&#xff0c;侵權刪&#xff0c;干貨滿滿。 原文鏈接&#xff1a;CUDA編程-03:線程層級 DeepDriving | CUDA編程-01&#xff1a; 搭建CUDA編程環境-CSDN博客 DeepDriving | CUDA編程-02&#xff1a; 初識CUDA編程-C…

Linux之共享內存mmap用法實例(六十三)

簡介&#xff1a; CSDN博客專家&#xff0c;專注Android/Linux系統&#xff0c;分享多mic語音方案、音視頻、編解碼等技術&#xff0c;與大家一起成長&#xff01; 優質專欄&#xff1a;Audio工程師進階系列【原創干貨持續更新中……】&#x1f680; 優質專欄&#xff1a;多媒…

外賣霸王餐返利外賣會員卡小程序開發

外賣霸王餐返利外賣會員卡小程序開發 "社交電商賦能下的外賣返利小程序"是專為商家與用戶雙贏而設計的創新平臺。 以下是其開發方案的詳細步驟&#xff1a; 一、需求梳理&#xff1a;首先&#xff0c;我們需要明確小程序的核心功能和特色。包括設定活動類型、返利…

Python學習(3) 函數

定義 定義一個函數的格式&#xff1a; def 函數名(參數):執行代碼如果沒有參數&#xff0c;則稱為無參函數。 定義時小括號中寫的是形參&#xff08;形式參數&#xff09;&#xff0c;調用時寫的是實參&#xff08;實際參數&#xff09;。 調用 調用格式&#xff1a; def…

【Docker】Linux 系統(CentOS 7)安裝 Docker

文章目錄 對 VMware 軟件的建議官方說明文檔Docker安裝卸載舊版本docker設置倉庫開始安裝 docker 引擎最新版 Docker 安裝指定版本 Docker 安裝&#xff08;特殊需求使用&#xff09; 啟動 Docker查看 Docker 版本查看 Docker 鏡像設置 Docker 開機自啟動 驗證開機啟動是否生效…

自定義原生小程序頂部及獲取膠囊信息

需求&#xff1a;我需要將某個文字或者按鈕放置在小程序頂部位置 思路&#xff1a;根據獲取到的頂部信息來定義我需要放的這個元素樣式 * 這里我是定義某個指定頁面 json&#xff1a;給指定頁面的json中添加自定義設置 "navigationStyle": "custom" JS&am…

新時代AI浪潮下,程序員和產品經理如何入局AIGC領域?

當下&#xff0c;AI浪潮席卷全球&#xff0c;AIGC大模型技術已經成為當今技術領域的一個重要趨勢&#xff0c;對于產品經理來說&#xff0c;掌握這項技術不僅能夠增強他們的職業技能&#xff0c;還能在競爭激烈的職場中脫穎而出。 為什么呢&#xff1f; 把握AI時代的機遇 AI技…

StringMVC

目錄 一&#xff0c;MVC定義 二&#xff0c;SpringMVC的基本使用 2.1建立連接 - RequestMapping("/...") ?編輯 2.2請求 1.傳遞單個參數 2.傳遞多個參數 3.傳遞對象 4.參數重命名 5.傳遞數組 6. 傳遞集合 7.傳遞JSON數據 8. 獲取url中數據 9. 傳遞文…

怎么通過OpenAI API調用其多模態大模型(GPT-4o)

現在只要有額度&#xff0c;大家都可以調用OpenAI的多模態大模型了&#xff0c;例如GPT-4o和GPT-4 Turbo&#xff0c;我一年多前總結過一些OpenAI API的用法&#xff0c;發現現在稍微更新了一下。主要參考了這里&#xff1a;https://platform.openai.com/docs/guides/vision 其…

python數據類型之元組、集合和字典

目錄 0.三者主要作用 1.元組 元組特點 創建元組 元組解包 可變和不可變元素元組 2.集合 集合特點 創建集合 集合元素要求 集合方法 訪問與修改 子集和超集 相等性判斷 集合運算 不可變集合 3.字典 字典特點 字典創建和常見操作 字典內置方法 pprin模塊 0.…

k8s——Pod詳解

一、Pod基礎概念 1.1 Pod定義 Pod是kubernetes中最小的資源管理組件&#xff0c;Pod也是最小化運行容器化應用的資源對象。一個Pod代表著集群中運行的一個進程。kubernetes中其他大多數組件都是圍繞著Pod來進行支撐和擴展Pod功能的&#xff0c;例如&#xff0c;用于管理Pod運行…

繆爾賽思又來到了你的面前(哈希)

定義一棵根節點為 1 1 1&#xff0c; n ( 2 ≤ n ≤ 1 0 3 ) n(2≤n≤10^3) n(2≤n≤103) 個節點的樹的哈希值為&#xff1a; H ∑ i 1 n X i Y f a ( i ) m o d 998244353 H∑^n_{i1}X^iY^{fa(i)}\ mod\ 998244353 Hi1∑n?XiYfa(i) mod 998244353 f a ( i ) fa(i) fa(i)…

斷網之后的頁面,Autox.js是點擊還是上下滑動比較好?

在處理斷網之后的頁面&#xff0c;選擇點擊還是上下滑動作為刷新操作&#xff0c;取決于應用的設計和用戶界面。通常&#xff0c;這兩種操作都可以作為刷新頁面的方式&#xff0c;但它們各自有不同的適用場景&#xff1a; 點擊刷新 - 適用場景&#xff1a;如果應用提供了一個明…

Java進階學習筆記7——權限修飾符

什么是權限修飾符&#xff1f; 就是用來限制類中的成員&#xff08;成員變量、成員方法、構造器、代碼塊....&#xff09;能夠被訪問的范圍。 protected使用的比較少&#xff0c;但是程序員還是要閱讀代碼&#xff0c;看官方文檔是怎么寫的&#xff0c;都會接觸到protected修飾…

C#串口通信-串口相關參數介紹

串口通訊(Serial Communication)&#xff0c;是指外設和計算機間&#xff0c;通過數據信號線、地線等&#xff0c;按位進行傳輸數據的一種雙向通訊方式。 串口是一種接口標準&#xff0c;它規定了接口的電氣標準&#xff0c;沒有規定接口插件電纜以及使用的通信協議&#xff0c…