spring boot 整合 minio存儲 【使用篇】

導入依賴

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

yml配置(默認配置)

max-file-size: 200MB 設置文件最大上傳大小為200MB,超過則返回錯誤信息并拒絕文件上傳

max-request-size: 100MB 這個配置項指定了整個請求的最大大小限制,包括所有文件和表單數據的大小。如果請求大小超過這個限制,將會拒絕請求并返回錯誤。

enabled:true?這個配置項指定了文件上傳功能是否啟用,設置為true表示啟用文件上傳功能,設置為false表示禁用文件上傳功能。當禁用文件上傳功能時,任何文件上傳請求都將被拒絕。

minion的配置和oss很像,都是這幾個需要注入的值

spring:# 配置文件上傳大小限制servlet:multipart:max-file-size: 200MBmax-request-size: 200MBenabled: true
minio:endpoint: http://127.0.0.1:9000accessKey: minioadminsecretKey: minioadminbucketName: bucket-qhj

該圖和上面minio配置對應

補充:由于每次啟動minio.exe要進入對應目錄,很麻煩,所以可以寫個批處理文件.bat

  1. @echo off:這是批處理文件的第一行,表示關閉命令回顯,即不在命令執行前顯示命令本身。

  2. echo.:顯示一個空行,這樣可以讓輸出信息更加清晰。

  3. echo [信息] 運行MinIO文服務器。:輸出提示信息,告訴用戶即將運行MinIO文服務器。

  4. title minio:設置窗口標題為 "minio"。

  5. D:? 代表進入D盤

  6. cd D:\Program Files\minio 代表進入你minio.exe存放的根目錄

    minio.exe server D:\MineFile\zuoye\xm\minioFile --console-address ":9999"?在D:\MineFile\zuoye\xm\minioFile文件夾執行,并且增加額外端口’9999‘

@echo off
echo.
echo [信息] 運行MinIO文服務器。
echo.title minioD:
cd D:\Program Files\miniominio.exe server D:\MineFile\zuoye\xm\minioFile --console-address ":9999"
pause

配置類

注入客戶端配置放入bean

@Data注解:

? ? ? ? 自動生成java類的標準方法,getter,setter,toString,equals,hashCode方法等

@Component

? ? ? ? 這個注解標識 MinIoClientConfig 類作為一個組件(bean)交給 Spring 容器管理,這樣其他地方就可以通過依賴注入來使用該類。

value注解

????????裝配yml配置文件中的值

@Bean注解

????????把minioClient方法注入容器交給 Spring 容器管理

@Data
@Component
public class MinIoClientConfig {@Value("${minio.endpoint}")private String endpoint;@Value("${minio.accessKey}")private String accessKey;@Value("${minio.secretKey}")private String secretKey;/*** 注入minio 客戶端* @return*/@Beanpublic MinioClient minioClient(){return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();}}

實體類

用于工具類的調用暫存

@Data
public class ObjectItem {private String objectName;private Long size;
}

工具類

根據實體類

/*** @description: minio工具類* @version:3.0*/
@Component
public class MinioUtilS {@Autowiredprivate MinioClient minioClient;@Value("${minio.bucketName}")private String bucketName;/*** description: 判斷bucket是否存在,不存在則創建** @return: void*/public void existBucket(String name) {try {boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build());if (!exists) {minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build());}} catch (Exception e) {e.printStackTrace();}}/*** 創建存儲bucket* @param bucketName 存儲bucket名稱* @return Boolean*/public Boolean makeBucket(String bucketName) {try {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** 刪除存儲bucket* @param bucketName 存儲bucket名稱* @return Boolean*/public Boolean removeBucket(String bucketName) {try {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** description: 上傳文件** @param multipartFile* @return: java.lang.String*/public List<String> upload(MultipartFile[] multipartFile) {List<String> names = new ArrayList<>(multipartFile.length);for (MultipartFile file : multipartFile) {String fileName = file.getOriginalFilename();String[] split = fileName.split("\\.");if (split.length > 1) {fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1];} else {fileName = fileName + System.currentTimeMillis();}InputStream in = null;try {in = file.getInputStream();minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(in, in.available(), -1).contentType(file.getContentType()).build());} catch (Exception e) {e.printStackTrace();} finally {if (in != null) {try {in.close();} catch (IOException e) {e.printStackTrace();}}}names.add(fileName);}return names;}/*** description: 下載文件** @param fileName* @return: org.springframework.http.ResponseEntity<byte [ ]>*/public ResponseEntity<byte[]> download(String fileName) {ResponseEntity<byte[]> responseEntity = null;InputStream in = null;ByteArrayOutputStream out = null;try {in = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());out = new ByteArrayOutputStream();IOUtils.copy(in, out);//封裝返回值byte[] bytes = out.toByteArray();HttpHeaders headers = new HttpHeaders();try {headers.add("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));} catch (UnsupportedEncodingException e) {e.printStackTrace();}headers.setContentLength(bytes.length);headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);headers.setAccessControlExposeHeaders(Arrays.asList("*"));responseEntity = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);} catch (Exception e) {e.printStackTrace();} finally {try {if (in != null) {try {in.close();} catch (IOException e) {e.printStackTrace();}}if (out != null) {out.close();}} catch (IOException e) {e.printStackTrace();}}return responseEntity;}/*** 查看文件對象* @param bucketName 存儲bucket名稱* @return 存儲bucket內文件對象信息*/public List<ObjectItem> listObjects(String bucketName) {Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());List<ObjectItem> objectItems = new ArrayList<>();try {for (Result<Item> result : results) {Item item = result.get();ObjectItem objectItem = new ObjectItem();objectItem.setObjectName(item.objectName());objectItem.setSize(item.size());objectItems.add(objectItem);}} catch (Exception e) {e.printStackTrace();return null;}return objectItems;}/*** 批量刪除文件對象* @param bucketName 存儲bucket名稱* @param objects 對象名稱集合*/public Iterable<Result<DeleteError>> removeObjects(String bucketName, List<String> objects) {List<DeleteObject> dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList());Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build());return results;}
}

控制器類

返回可訪問的url

@RestController:

???????? 這個注解表示該類是一個 RESTful 服務的控制器,用于處理 HTTP 請求并返回 JSON 格式的響應。

@Slf4j:

????????這是 lombok 提供的注解,用于自動生成日志 Logger 對象,可以通過 log 對象進行日志輸出。

@RestController
@Slf4j
@RequestMapping("/fileSave")
public class MinioController {@Autowiredprivate MinIoUtil minIoUtil;@Autowiredprivate MinioUtilS minioUtilS;@Value("${minio.endpoint}")private String address;@Value("${minio.bucketName}")private String bucketName;@RequestMapping("/fileInMinio")public R uploadInMinio(MultipartFile file) {List<String> upload = minioUtils.upload(new MultipartFile[]{file});String url = address + "/" + bucketName + "/" + upload.get(0);return R.ok().put("filePath", url);}}

上傳后獲取鏈接為

訪問報錯

解決方式

來到minio控制臺

打開你正在使用的bucket

修改訪問權限為public就行

重新訪問鏈接,應該就能查看

前端代碼

通過父組件導入子組件,注冊子組件,引用子組件彈出

父組件調用方法

    // 文件導入importExcel () {this.uploadFileVisible = truethis.$nextTick(() => {this.$refs.uploadFile.init()})}

?子組件vue頁面

包含三種上傳方式的切換

<template><el-dialogtitle="維修處理":close-on-click-modal="true":visible.sync="visible"><el-selectsize="small"v-model="uploadMethodValue"placeholder="請選擇上傳方式"clearable=""filterable><el-optionv-for="d in uploadMethod":key="d.value":label="d.name":value="d.value"></el-option></el-select><el-uploadclass="upload-demo"ref="upload"dragaction="#":on-change="handleChangeSelect":on-exceed="handleExceed":file-list="fileList":limit="1"multiple:auto-upload="false"><i class="el-icon-upload"></i><div class="el-upload__text">將文件拖到此處,或<em>點擊上傳</em></div><divclass="el-upload__tip"slot="tip">只能上傳jpg/png文件,且不超過500kb</div><divclass="el-upload__tip"slot="tip">訪問路徑:{{ filePath }}</div></el-upload></el-dialog>
</template><script>
export default {data () {return {// 對話框顯示狀態visible: false,uploadMethod: [{ name: '本地存儲', value: '1' },{ name: 'oss存儲', value: '2' },{ name: 'miniio', value: '3' }],// 選中的上傳方式uploadMethodValue: '',// 表單數據dataForm: {},filePath: '',fileList: []}},methods: {// 初始化方法init () {this.visible = truethis.filePath = ''},// 文件超出個數提示handleExceed (files, fileList) {this.$message.warning(`當前限制選擇 1 個文件,本次選擇了 ${files.length} 個文件,共選擇了 ${files.length + fileList.length} 個文件`)},handleChangeSelect (file) {if (this.uploadMethodValue === '1') {// 本地存儲this.handleChange(file, '/fileSave/file')} else if (this.uploadMethodValue === '2') {// oss存儲this.handleChange(file, '/fileSave/fileInOSS')} else if (this.uploadMethodValue === '3') {// miniiothis.handleChange(file, '/fileSave/fileInMinio')}},handleChange (file, urlSelect) {let formData = new FormData()formData.append('file', file.raw) // 傳文件this.$http({url: this.$http.adornUrl(urlSelect),method: 'post',data: formData,headers: {'Content-Type': 'multipart/form-data'}}).then(({ data }) => {if (data && data.code === 0) {this.filePath = data.filePaththis.$message({message: '操作成功',type: 'success',duration: 1500})} else {this.$message.error(data.msg)}this.$refs.upload.clearFiles() // 清除文件})}}
}</script>

拓展學習

MultipartFile

?MultipartFile為org.springframework.web.mutipart包下的一個類,也就是說如果想使用MultipartFile這個類就必須引入spring框架,換句話說,如果想在項目中使用MultipartFile這個類,那么項目必須要使用spring框架才可以,否則無法引入這個類。

一般來講使用MultipartFile這個類主要是來實現以表單的形式進行文件上傳功能。

MiltipartFile類注釋說明

?第一句:一種可以接收使用多種請求方式來進行上傳文件的代表形式。也就是說,如果你想用spring框架來實現項目中的文件上傳功能,則MultipartFile可能是最合適的選擇,而這里提到的多種請求方式則可以通俗理解為以表單的形式提交。

? ? ? 第二句:這個文件內容可以存儲到內存中或者存儲在磁盤的臨時位置上。

? ? ? 第三句:無論發生哪種情況,用戶都可以自由地拷貝文件內容到session存儲中,或者以一種永久存儲的形式進行存儲,如果有需要的話。

? ? ? 第四句:這種臨時性的存儲在請求結束之后將會被清除掉。

類中方法

?getName方法

獲取的是前后端約定的傳入文件的參數的名稱,在SpringBoot后臺中則是通過@Param("uploadFile")?注解定義的內容。

getOriginalFileName方法?

getOriginalFileName方法獲取的是文件的完整名稱,包括文件名稱+文件拓展名。

getContentType方法?

getContentType方法獲取的是文件的類型,注意是文件的類型,不是文件的拓展名。

getBytes方法?

getBytes方法用來將文件轉換成一種字節數組的方式進行傳輸,會拋出IOException異常。

getInputStream方法?

getInputStream方法用來將文件轉換成輸入流的形式來傳輸文件,會拋出IOException異常。

transferTo方法?

transferTo方法用來將接收文件傳輸到給定目標路徑,會拋出IOException、IllegalStateException異常。該方法在實際項目開發中使用較少。

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

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

相關文章

華為od機試C卷-開源項目熱度榜單

1、題目描述 某個開源社區希望將最近熱度比較高的開源項目出一個榜單&#xff0c;推薦給社區里面的開發者。 對于每個開源項目&#xff0c;開發者可以進行關注(watch)、收藏(star)、fork、提issue、提交合并請求(MR)等。 數據庫里面統計了每個開源項目關注、收藏、fork、issue…

微服務API網關---APISIX

最近在做微服務調研&#xff0c;看到了apisix這個網關&#xff0c;于是進行了初步了解一下。 微服務是指&#xff0c;將大型應用分解成多個獨立的組件&#xff0c;其中每個組件都各自的負責對應項目。 系統的架構大致經歷了&#xff1a;單體應用架構–> SOA架構 -->微服務…

Linux多線程服務端編程:使用muduo C++網絡庫 學習筆記 附錄D 關于TCP并發連接的幾個思考題與試驗

前幾天作者在新浪微博上出了兩道有關TCP的思考題&#xff0c;引發了一場討論&#xff08;http://weibo.com/1701018393/eCuxDrtaONn&#xff09;。 第一道初級題目是&#xff1a;有一臺機器&#xff0c;它有一個IP&#xff0c;上面運行了一個TCP服務程序&#xff0c;程序只偵聽…

StarRocks實戰——松果出行實時數倉實踐

目錄 一、背景 二、松果出行實時OLAP的演進 2.1 實時數倉1.0的架構 2.2 實時數倉2.0的架構 2.3 實時數倉3.0的架構 三、StarRocks 的引入 四、StarRocks在松果出行的應用 4.1 在訂單業務中的應用 4.2 在車輛方向的應用 4.3 StarRocks “極速統一” 落地 4.4 StarRoc…

Lambda、Function、StreamAPI詳解

目錄 1、Lambda 2、Function 3、StreamAPI 中間操作&#xff1a;Intermediate Operations 終止操作&#xff1a;Terminal Operation 1、Lambda Java8語法糖&#xff1a;參數列表 箭頭 方法體 package com.atguiggu.lambda;import java.util.*; import java.util.funct…

分布式ID生成系統之雪花算法詳解

在當今的云計算和微服務架構盛行的時代&#xff0c;分布式系統已成為軟件開發的重要組成部分。隨著系統規模的擴大和業務的復雜化&#xff0c;對數據一致性和唯一性的要求也越來越高&#xff0c;尤其是在全局唯一標識符&#xff08;ID&#xff09;的生成上。因此&#xff0c;分…

代碼隨想錄算法訓練營Day48 | 121.買賣股票的最佳時機、122.買賣股票的最佳時機 II

121.買賣股票的最佳時機 &#xff08;想寫動態規劃寫著寫著變成貪心了&#xff09; 半貪心半動規&#xff1a; int maxProfit(vector<int>& prices) {vector<int> dp(prices.size(), 0);int minVal prices[0];for (int i 1; i < prices.size(); i) {//…

yolov5訓練太慢的解決方案

問題原因 訓練太慢大多是因為沒有安裝CUDA和pytorch&#xff0c;導致的只有cpu在跑&#xff0c;顯卡沒跑 這就是很典型的。 解決方案 第一步&#xff1a;安裝CUDA 在本機上面安裝CUDA,記住只有N卡可以安裝&#xff0c;一開始的電腦是自帶CUDA的。 如果不是自帶的CUDA&…

Apache Paimon Flink引擎解析

Paimon 支持 Flink 1.17, 1.16, 1.15 和 1.14&#xff0c;當前 Paimon 提供了兩類 Jar 包&#xff0c;一類支持數據讀寫&#xff0c;另一類支持其它操作&#xff08;compaction&#xff09; Version Type Jar Flink 1.18 Bundled Jar paimon-flink-1.18-0.7…

SentenceTransformer簡單使用

SentenceTransformer簡單使用 1 SentenceTransformer介紹 SentenceTransformer主要用于對句子、文本和圖像進行嵌入。可用于文本和圖像的相似度對比查找等 # SentenceTransformer官網地址 https://www.sbert.net/# 安裝SentenceTransformer pip install -U sentence-transfo…

求數字的每一位之和

求數字的每一位之和 題目描述&#xff1a;解法思路&#xff1a;解法代碼&#xff1a;運行結果&#xff1a; 題目描述&#xff1a; 輸入一個整數m&#xff0c;求這個整數m的每?位之和&#xff0c;并打印。 測試1&#xff1a; 輸?&#xff1a;1234 輸出&#xff1a;10 測試2&…

土壤侵蝕量化評估

根據之前的文章,已經算出了R、K、LS、C、P 現在計算土壤侵蝕,將幾個前期制作好的因子的TIFF文件,用柵格計算器相乘 發現局部地區存在輕度侵蝕,大部分區域是微度侵蝕 然后對比了一下范圍 其中的幾個因子都在文獻范圍內,說明計算結果并未出錯,可能就是研究區正常范圍和結…

6020一拖二快充線:手機充電的革命性創新

在快節奏的現代生活中&#xff0c;手機已不僅僅是一個通訊工具&#xff0c;更是我們工作、學習和娛樂的得力助手。然而&#xff0c;手機的電量問題一直是困擾著我們的難題。為了解決這個問題&#xff0c;市場上出現了一種名為“一拖二快充線”的充電設備&#xff0c;它不僅具備…

etcd入門-(1)安裝篇

一、etcd安裝 https://github.com/etcd-io/etcd/releases 根據需要下載安裝etcd, 確保添加到環境變量 執行 etcd -v 查看安裝版本 二、etcd運行 本地運行集群 1.首先安裝goreman go install github.com/mattn/goremanlatest2.準備Procfile 將腳本下載到本地&#xff0c;或者復…

八. 實戰:CUDA-BEVFusion部署分析-分析BEVFusion中各個ONNX

目錄 前言0. 簡述1. camera.backbone.onnx(fp16)2. camera.backbone.onnx(int8)3. camera.vtransform.onnx(fp16)4. fuser.onnx(fp16)5. fuser.onnx(int8)6. lidar.backbone.xyz.onnx7. head.bbox.onnx(fp16)總結下載鏈接參考 前言 自動駕駛之心推出的《CUDA與TensorRT部署實戰…

每日一類:Qt中的萬能容器

在Qt框架中&#xff0c;QVariant類扮演著一個非常重要的角色。它是一個萬能容器類&#xff0c;可以存儲Qt中的任何基本類型數據&#xff0c;包括自定義類型。這種靈活性使得QVariant成為Qt編程中不可或缺的工具&#xff0c;特別是在需要處理不同類型數據或進行對象間通信時。 …

Unity UGUI之Scrollbar基本了解

Unity的Scrollbar組件是用于在UI中創建滾動條的組件之一。滾動條通常與其他可滾動的UI元素&#xff08;如滾動視圖或列表&#xff09;一起使用&#xff0c;以便用戶可以在內容超出可見區域時滾動內容。 以下是Scrollbar的基本信息和用法: 1、創建 在Unity的Hierarchy視圖中右…

柯西矩陣介紹

經典定義 柯西矩陣&#xff08;Cauchy Matrix&#xff09;&#xff0c;是一種特殊類型的矩陣&#xff0c;它在數學中的多個領域&#xff0c;包括線性代數、數值分析和插值理論中都有重要應用。柯西矩陣以19世紀法國數學家奧古斯丁-路易柯西的名字命名。 柯西矩陣是一個方陣&am…

Krylov matrix

Krylov矩陣是一種在數值線性代數中使用的矩陣&#xff0c;尤其是在迭代解法中用于求解線性方程組、特征值問題和其他線性代數問題。它是由俄國數學家阿列克謝尼古拉耶維奇克雷洛夫&#xff08;Alexei Nikolaevich Krylov&#xff09;的名字命名的。 Krylov子空間由以下形式的矩…

jetson nano——編譯安裝opencv==4.4

目錄 1.下載源碼&#xff0c;我提供的鏈接如下&#xff1a;1.1文件上傳的路徑位置&#xff0c;注意ymck是我自己的用戶名&#xff08;你們自己換成你們自己相對應的就行&#xff09; 2.解壓文件3.安裝依賴4.增加swap交換內存4.1臨時增加交換內存swap4.2永久增加swap 5.安裝open…