SpringBoot整合Minio

SpringBoot整合Minio

在企業開發中,我們經常會使用到文件存儲的業務,Minio就是一個不錯的文件存儲工具,下面我們來看看如何在SpringBoot中整合Minio

POM

pom文件指定SpringBoot項目所依賴的軟件工具包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.zsxq</groupId><artifactId>csg_idc_zsxq</artifactId><version>0.0.1-SNAPSHOT</version><name>csg_idc_zsxq</name><description>csg_idc_zsxq</description><properties><java.version>17</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.7.3</spring-boot.version></properties><dependencies><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http</artifactId><version>3.5.1</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxws</artifactId><version>3.5.1</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.12</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.7.7</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.16</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.12</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.26</version></dependency><!--minio--><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.0.3</version></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>17</source><target>17</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><configuration><mainClass>com.idc.zsxq.CsgIdcZsxqApplication</mainClass><skip>true</skip></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>

YML

SpringBoot配置文件

server:port: 11112
# springdoc-openapi項目配置
knife4j:enable: truesetting:language: zh_cn
spring:redis:password:host: 127.0.0.1port: 6379username:
# minio
minio:endpoint: http://127.0.0.1:9000accessKey: minioadminsecretKey: minioadminbucketName: bucket

MinioClientConfig

Minio的配置類

package com.idc.zsxq.config;import io.minio.MinioClient;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@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();}}

MinioUtil

操作Minio的工具類,實現了判斷Bucket是否存在,創建Bucket,上傳文件,下載文件等功能

package com.idc.zsxq.util;import com.idc.zsxq.model.ObjectItem;
import io.minio.*;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;/*** @description: minio工具類* @version:3.0*/
@Component
public class MinioUtil {@Resourceprivate 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 in* @return: InputStream*/public void upload(InputStream in, String bucketName, String fileName) {try {minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(in, in.available(), -1).contentType("application/octet-stream;charset=UTF-8").build());} catch (Exception e) {e.printStackTrace();} finally {try {in.close();} catch (IOException e) {e.printStackTrace();}}}/*** description: 下載文件** @param fileName* @return: org.springframework.http.ResponseEntity<byte [ ]>*/public ResponseEntity<byte[]> download(String fileName, String bucketName) {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();}//需要設置此屬性,否則瀏覽器默認不會讀取到響應頭中的Accept-Ranges屬性,因此會認為服務器端不支持分片,所以會直接全文下載headers.add("Access-Control-Expose-Headers", "Accept-Ranges,Content-Range");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;}}

案例

在SpringBoot中如何使用MinioUtil操作Minio,一般我們會使用Minio當做文件緩存

下面這個案例實現了下載文件的功能,邏輯:先從Minio查找是否存在文件,如果存在則從Minio下載文件,如果不存在則從遠程文件服務器下載文件

//獲取文件
public byte[] downloadFile(String bucketName, String fileId, String newFileId) {log.info("下載文件 開始");// 測試bucketName = "library";fileId = "6cc750db08c943b48a259020ce4e6794";newFileId = "0fe8cb9eb5954cc2876c3ac8496692a7";String fileName = bucketName + "_" + fileId + "_" +(newFileId == null ? "" : newFileId);log.info("文件名 {}", fileName);try {//如果沒有bucket,則創建minioUtil.existBucket(bucketName);//判斷Minio中是否有該文件List<ObjectItem> objectItems = minioUtil.listObjects(bucketName);boolean flag = false;if (CollectionUtil.isNotEmpty(objectItems)) {for (ObjectItem o : objectItems) {if (StringUtils.equals(o.getObjectName(), fileName)) {flag = true;break;}}}byte[] bytes = null;//如果有,則從Minio中獲取文件if (flag) {log.info("從Minio獲取文件");ResponseEntity<byte[]> download = minioUtil.download(fileName, bucketName);bytes = download.getBody();} else {log.info("從文件服務器獲取文件");//如果Minio沒有,則從文件服務器獲取文件,如果報錯,則拋出異常//封裝基本查詢參數urlString withParamsUrl = CnkiUrlEnum.DOWNLOAD_FILE.getUrl() + "?fileId=" + fileId +(StringUtils.isEmpty(newFileId) ? "" : "&newFileId=" + newFileId) +"&bucketName=" + bucketName;HttpResponse httpResponse = HttpRequest.post(withParamsUrl).header("accessToken", ConstantEnum.TOKEN.getValue()).body("").execute();String status = httpResponse.getStatus() + "";//判斷是否請求成功if (!"200".equals(status) && !"204".equals(status)) {log.error("數據庫查詢異常, CNKI接口返回狀態碼為:" + status);throw new BusinessException(ResultEnum.ERROR);}//空文件拋出異常if (StringUtils.equals(httpResponse.header("Content-Type"), "application/json")) {String jsonBody = httpResponse.body();JSONObject dataJson = JSONObject.parseObject(jsonBody);String dataCode = dataJson.getString("code");log.error("文件內容為空 : " + dataCode);throw new BusinessException(ResultEnum.ERROR);}//獲取文件字節流bytes = httpResponse.bodyBytes();//寫入MiniominioUtil.upload(new ByteArrayInputStream(bytes), bucketName, fileName);}log.info("下載文件 結束");//寫到響應流中return bytes;} catch (Exception e) {log.error("下載文件報錯 : {}", e);}return new byte[]{};}

效果

通過postman調用接口,返回文件流

image-20230815101451026

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

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

相關文章

Ubuntu上安裝RabbitMQ

在Ubuntu上安裝RabbitMQ并設置管理員用戶為"admin"&#xff0c;密碼為"123456"&#xff0c;并開啟開機自啟 更新系統軟件包列表。在終端中執行以下命令&#xff1a; sudo apt update安裝RabbitMQ服務器軟件包。運行以下命令&#xff1a; sudo apt insta…

DaVinci Resolve Studio 18 for Mac 達芬奇調色

DaVinci Resolve Studio 18是一款專業的視頻編輯和調色軟件&#xff0c;適用于電影、電視節目、廣告等各種視覺媒體的制作。它具有完整的后期制作功能&#xff0c;包括剪輯、調色、特效、音頻處理等。 以下是DaVinci Resolve Studio 18的主要特點&#xff1a; - 提供了全面的視…

Linux 設置 ssh 內網穿透

背景&#xff1a;有三臺機器A、B、C&#xff0c;機器 A 位于某局域網內&#xff0c;能夠連接到互聯網。機器 B 有公網 IP&#xff0c;能被 A 訪問到。機器 C 位于另外一個局域網內&#xff0c;能夠連接到互聯網&#xff0c;能夠訪問 B。 目標&#xff1a;以 B 為中介&#xff…

Jmeter-壓測時接口按照順序執行-臨界部分控制器

文章目錄 臨界部分控制器存在問題 臨界部分控制器 在進行壓力測試時&#xff0c;需要按照順序進行壓測&#xff0c;比如按照接口1、接口2、接口3、接口4 進行執行 查詢結果是很混亂的&#xff0c;如果請求次數少&#xff0c;可能會按照順序執行&#xff0c;但是隨著次數增加&a…

Python-OpenCV中的圖像處理-模板匹配

Python-OpenCV中的圖像處理-模板匹配 模板匹配單對象的模板匹配多對象的模板匹配 模板匹配 使用模板匹配可以在一幅圖像中查找目標函數&#xff1a; cv2.matchTemplate()&#xff0c; cv2.minMaxLoc()模板匹配是用來在一副大圖中搜尋查找模版圖像位置的方法。 OpenCV 為我們提…

無線充電底座

<項目>無線充電器 前言 個人DIY的無線充電底座&#xff08;帶磁吸&#xff09;&#xff0c;基于IP6829方案。 Drawn By:67373 硬件部分 3D模型 資料開源鏈接 https://github.com/linggan17/WirelessCharge

面試熱題(每日溫度)

請根據每日 氣溫 列表 temperatures &#xff0c;重新生成一個列表&#xff0c;要求其對應位置的輸出為&#xff1a;要想觀測到更高的氣溫&#xff0c;至少需要等待的天數。如果氣溫在這之后都不會升高&#xff0c;請在該位置用 0 來代替。 輸入: temperatures [73,74,75,71,69…

SpringBoot + Mybatis多數據源

一、配置文件 spring: # datasource: # username: root # password: 123456 # url: jdbc:mysql://127.0.0.1:3306/jun01?characterEncodingutf-8&serverTimezoneUTC # driver-class-name: com.mysql.cj.jdbc.Driverdatasource:# 數據源1onedata:jdbc-url: j…

SCF金融公鏈新加坡啟動會 鏈結創新驅動未來

新加坡迎來一場引人矚目的金融科技盛會&#xff0c;SCF金融公鏈啟動會于2023年8月13日盛大舉行。這一受矚目的活動將為金融科技領域注入新的活力&#xff0c;并為廣大投資者、合作伙伴以及關注區塊鏈發展的人士提供一個難得的交流平臺。 在SCF金融公鏈啟動會上&#xff0c; Wil…

CentOS7的journalctl日志查看方法

多臺服務器間免密登錄|免密拷貝 Cenos7 搭建Minio集群部署服務器(一) Cenos7 搭建Minio集群Nginx統一訪問入口|反向動態代理(二) Spring Boot 與Minio整合實現文件上傳與下載(三) CentOS7的journalctl日志查看方法 MySQL8.xx一主兩從復制安裝與配置 1、概述 日志管理工…

【ElasticSearch入門】

目錄 1.ElasticSearch的簡介 2.用數據庫實現搜素的功能 3.ES的核心概念 3.1 NRT(Near Realtime)近實時 3.2 cluster集群&#xff0c;ES是一個分布式的系統 3.3 Node節點&#xff0c;就是集群中的一臺服務器 3.4 index 索引&#xff08;索引庫&#xff09; 3.5 type類型 3.6 doc…

【佳佳怪文獻分享】MVFusion: 利用語義對齊的多視角 3D 物體檢測雷達和相機融合

標題&#xff1a;MVFusion: Multi-View 3D Object Detection with Semantic-aligned Radar and Camera Fusion 作者&#xff1a;Zizhang Wu , Guilian Chen , Yuanzhu Gan , Lei Wang , Jian Pu 來源&#xff1a;2023 IEEE International Conference on Robotics and Automat…

kubernetes企業級高可用部署

目錄 1、Kubernetes高可用項目介紹 2、項目架構設計 2.1、項目主機信息 2.2、項目架構圖 1、Kubernetes高可用項目介紹 2、項目架構設計 2.1、項目主機信息 2.2、項目架構圖 2.3、項目實施思路 3、項目實施過程 3.1、系統初始化 3.2、配置部署keepalived服務 3.3、…

強制Edge或Chrome使用獨立顯卡【WIN10】

現代瀏覽器通常將圖形密集型任務卸載到 GPU&#xff0c;以改善你的網頁瀏覽體驗&#xff0c;從而釋放 CPU 資源用于其他任務。 如果你的系統有多個 GPU&#xff0c;Windows 10 可以自動決定最適合 Microsoft Edge 自動使用的 GPU&#xff0c;但這并不一定意味著最強大的 GPU。 …

Linux/centos上如何配置管理NFS服務器?

Linux/centos上如何配置管理NFS服務器&#xff1f; 1 NFS基礎了解1.1 NFS概述1.2 NFS工作流程 2 安裝和啟動NFS服務2.1 安裝NFS服務器2.2 啟動NFS服務 3 配置NFS服務器和客戶端3.1 配置NFS服務器3.2 配置NFS客戶端 4 實際示例4.1 基本要求4.2 案例實現 1 NFS基礎了解 NFS&…

LAXCUS如何通過技術創新管理數千臺服務器

隨著互聯網技術的不斷發展&#xff0c;服務器已經成為企業和個人獲取信息、進行計算和存儲的重要工具。然而&#xff0c;隨著服務器數量的不斷增加&#xff0c;傳統的服務器管理和運維方式已經無法滿足現代企業的需求。LAXCUS做為專注服務器集群的【數存算管】一體化平臺&#…

Jtti:Windows server如何備份與還原注冊表

在 Windows Server 中&#xff0c;備份和還原注冊表是一項重要的任務&#xff0c;可以幫助你在系統配置更改之前創建一個恢復點&#xff0c;以防止出現問題。以下是在 Windows Server 上備份和還原注冊表的步驟&#xff1a; 備份注冊表&#xff1a; 1.打開“運行”對話框&…

企業數據庫遭到360后綴勒索病毒攻擊,360勒索病毒解密

在當今數字化時代&#xff0c;企業的數據安全變得尤為重要。隨著數字化辦公的推進&#xff0c;企業的生產運行效率得到了很大提升&#xff0c;然而針對網絡安全威脅&#xff0c;企業也開始慢慢引起重視。近期&#xff0c;我們收到很多企業的求助&#xff0c;企業的服務器遭到了…

代理模式(Java實現)

代理模式是常見的設計模式之一&#xff0c;顧名思義&#xff0c;代理模式就是代理對象具備真實對象的功能&#xff0c;并代替真實對象完成相應操作&#xff0c;并能夠在操作執行的前后&#xff0c;對操作進行增強處理。&#xff08;為真實對象提供代理&#xff0c;然后供其他對…

threejs使用gui改變相機的參數

調節相機遠近角度 定義相機的配置&#xff1a; const cameraConfg reactive({ fov: 45 }) gui中加入調節fov的方法 const gui new dat.GUI();const cameraFolder gui.addFolder("相機屬性設置");cameraFolder.add(cameraConfg, "fov", 0, 100).name(…