欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

springboot整合minio的超詳細(xì)教程

 更新時間:2023年12月19日 09:22:11   作者:逆風(fēng)飛翔的小叔  
在很多互聯(lián)網(wǎng)產(chǎn)品應(yīng)用中,都涉及到各種與文件存儲相關(guān)的業(yè)務(wù),隨著技術(shù)的發(fā)展,關(guān)于如何解決分布式文件存儲也有了比較成熟的方案,比如私有云部署下可以考慮fastdfs,阿里云對象存儲oss,七牛云等,本篇將為你介紹另一種文件存儲方式,即MinIO,需要的朋友可以參考下

一、前言

在很多互聯(lián)網(wǎng)產(chǎn)品應(yīng)用中,都涉及到各種與文件存儲相關(guān)的業(yè)務(wù),隨著技術(shù)的發(fā)展,關(guān)于如何解決分布式文件存儲也有了比較成熟的方案,比如私有云部署下可以考慮fastdfs,阿里云對象存儲oss,七牛云等,本篇將為你介紹另一種文件存儲方式,即MinIO 。

二、Minio 概述

2.1 Minio簡介

MinIO基于Apache License v2.0開源協(xié)議的對象存儲服務(wù),可以做為云存儲的解決方案用來保存海量的圖片,視頻,文檔,是一款高性能、分布式的對象存儲系統(tǒng), 可以100%的運(yùn)行在標(biāo)準(zhǔn)硬件,即X86等低成本機(jī)器也能夠很好的運(yùn)行MinIO。

傳統(tǒng)的存儲和其他的對象存儲不同的是:

它一開始就針對性能要求更高的私有云標(biāo)準(zhǔn)進(jìn)行軟件架構(gòu)設(shè)計。因?yàn)镸inIO一開始就只為對象存儲而設(shè)計。所以他采用了更易用的方式進(jìn)行設(shè)計,它能實(shí)現(xiàn)對象存儲所需要的全部功能,在性能上也更加強(qiáng)勁,它不會為了更多的業(yè)務(wù)功能而妥協(xié),失去MinIO的易用性、高效性。 這樣的結(jié)果所帶來的好處是:它能夠更簡單的實(shí)現(xiàn)局有彈性伸縮能力的原生對象存儲服務(wù)。

2.2 Minio特點(diǎn)

Minio具有如下特點(diǎn)

  • 性能高,準(zhǔn)硬件條件下它能達(dá)到55GB/s的讀、35GB/s的寫速率;
  • 部署自帶管理界面;
  • MinIO.Inc運(yùn)營的開源項(xiàng)目,社區(qū)活躍度高;
  • 提供了所有主流開發(fā)語言的SDK;
  • 基于Golang語言實(shí)現(xiàn),配置簡單,單行命令可以運(yùn)行起來;
  • 兼容亞馬遜S3云存儲服務(wù)接口,適合于存儲大容量非結(jié)構(gòu)化的數(shù)據(jù),一個對象文件可以是任意大小,從幾kb到最大5T不等;

三、Minio 環(huán)境搭建

本文采用docker的方式快速搭建起Minio的環(huán)境,也可以通過官網(wǎng)下載安裝包部署,官網(wǎng)安裝包下載地址

3.1 部署過程

3.1.1 拉取鏡像

docker pull minio/minio

3.1.2 啟動容器

docker run -d -p 9000:9000 -p 9090:9090 \
     --name minio \
     -e "MINIO_ACCESS_KEY=minio" \
     -e "MINIO_SECRET_KEY=minio" \
     -v /home/minio/data:/data \
     -v /home/minio/config:/root/.minio \
     minio/minio server \
     /data --console-address ":9090" -address ":9000"

3.1.3 訪問web頁面

容器啟動成功后,注意開發(fā)相關(guān)的防火墻端口即可,然后訪問地址:IP:9000,即可訪問Minio的web界面

輸入賬戶和密碼,登錄進(jìn)去之后,看到下面的效果說明Minio環(huán)境搭建完成

四、Minio基本使用

4.1 基本概念

在正式開始使用Minio之前,有必要先了解下幾個相關(guān)的概念

  • bucket ,類比于文件系統(tǒng)的目錄;
  • Object ,類比文件系統(tǒng)的文件;
  • Keys ,類比文件名;

4.2 上傳文件演示

如下,點(diǎn)擊創(chuàng)建一個新的bucket,創(chuàng)建完成后就可以在列表上看到這個bucket;

給當(dāng)前這個bucket上傳一個文件

點(diǎn)擊文件夾圖標(biāo)

上傳一張本地文件,上傳完成后就可以看到這個文件了,也可以瀏覽上傳的文件

4.3 用戶管理

針對客戶端的操作,經(jīng)常需要維護(hù)相關(guān)的賬號來管理,比如賬戶的操作權(quán)限,訪問控制等;

點(diǎn)擊,創(chuàng)建用戶

填寫用戶信息,勾選權(quán)限保存即可

然后在用戶列表就可以看到這個用戶了

4.4 Java操作Minio

通過上面的環(huán)境搭建和操作,演示并了解了如何快速使用Minio,更多的功能可以參閱相關(guān)資料進(jìn)一步學(xué)習(xí)了解,下面我們編寫java代碼完成文件的上傳。

4.4.1 導(dǎo)入依賴

在當(dāng)前的maven工程中導(dǎo)入minio的依賴,客戶端具體版本可以根據(jù)你的實(shí)際需要選擇

        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>7.1.0</version>
        </dependency>

4.4.2 上傳文件到minio

通過下面這段代碼將本地的一張圖片文件上傳到minio的test這個bucket目錄下

public static void main(String[] args) {
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream("F:\\網(wǎng)盤\\Title-logo.png");
            MinioClient client = MinioClient.builder().credentials("minio", "minio").endpoint("http://IP:9000").build();
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .object("logo.png")
                    .contentType("image/png")
                    .bucket("test")
                    .stream(inputStream, inputStream.available(), -1)
                    .build();
            client.putObject(putObjectArgs);
            System.out.println("上傳成功");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
 
    }

運(yùn)行這段代碼,上傳成功后,去到test的目錄下刷新之后可以看到文件已經(jīng)上傳

五、springboot整合Minio

接下來讓我們看看如何在springboot中集成Minio,參考下面的操作步驟

5.1 前置準(zhǔn)備

5.1.1 引入依賴

創(chuàng)建一個maven工程,引入如下相關(guān)的依賴

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
    </parent>
 
 
    <dependencies>
 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
 
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>7.1.0</version>
        </dependency>
 
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>
 
 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
 
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
 
    </dependencies>

5.1.2 核心配置文件

在配置文件中添加如下內(nèi)容

server:
  port: 8087
 
logging:
  level:
    root: info
    com.congge.model: debug
 
minio:
  username: minio
  pwd: minio
  bucket: test
  endpoint: http://IP:9000
  readPath: http://IP:9000

5.2 編碼過程

5.2.1 創(chuàng)建一個參數(shù)配置類

通過這種方式將配置文件中以minio開頭的那些配置加載到spring容器中管理,其他位置使用的時候直接注入即可

@Data
@ConfigurationProperties(prefix = "minio")
@Component
public class MinIOConfigProperties implements Serializable {
 
    private String username;
    private String pwd;
    private String bucket;
    private String endpoint;
    private String readPath;
 
}

5.2.2 創(chuàng)建minio配置類

通過這個全局的配置類,其他需要上傳文件的類中直接注入MinioClient即可

import io.minio.MinioClient;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Data
@Configuration
public class MinIOConfig {
 
    @Autowired
    private MinIOConfigProperties minIOConfigProperties;
 
    @Bean
    public MinioClient buildMinioClient() {
        return MinioClient
                .builder()
                .credentials(minIOConfigProperties.getAccessKey(), minIOConfigProperties.getSecretKey())
                .endpoint(minIOConfigProperties.getEndpoint())
                .build();
    }
}

5.2.3 創(chuàng)建minio文件服務(wù)類或工具類

在日常開發(fā)中,可以自定義一個minio的工具類,使用的時候就比較方便了,下面的代碼中列舉了常用的一些API操作方法,可以結(jié)合實(shí)際需要自定義更多的工具方法

 
import com.congge.config.MinIOConfig;
import com.congge.config.MinIOConfigProperties;
import com.congge.service.MinioFileService;
import io.minio.*;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.util.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
 
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
 
@Slf4j
@Import(MinIOConfig.class)
@Service
public class MinioFileServiceImpl implements MinioFileService {
 
    @Autowired
    private MinioClient minioClient;
 
    @Autowired
    private MinIOConfigProperties minIOConfigProperties;
 
    private final static String separator = "/";
 
    /**
     * 下載文件
     *
     * @param pathUrl 文件全路徑
     * @return 文件流
     */
    @Override
    public void downLoadFile(String pathUrl, HttpServletResponse response) {
        String[] pathItems = pathUrl.split("/");
        String originFileName = pathItems[pathItems.length - 1];
        String key = pathUrl.replace(minIOConfigProperties.getEndpoint() + "/", "");
        int index = key.indexOf(separator);
        //String bucket = key.substring(0,index);
        String filePath = key.substring(index + 1);
        InputStream inputStream = null;
        try {
            inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(minIOConfigProperties.getBucket()).object(filePath).build());
            response.setHeader("Content-Disposition", "attachment;filename=" + originFileName);
            response.setContentType("application/force-download");
            response.setCharacterEncoding("UTF-8");
            IOUtils.copy(inputStream, response.getOutputStream());
            System.out.println("下載成功");
        } catch (Exception e) {
            log.error("minio down file error.  pathUrl:{}", pathUrl);
            e.printStackTrace();
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
 
    @Override
    public String uploadFile(MultipartFile file) throws Exception {
        String bucketName = minIOConfigProperties.getBucket();
        String endpoint = minIOConfigProperties.getEndpoint();
 
        // 檢查存儲桶是否已經(jīng)存在
        boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        if (isExist) {
            System.out.println("Bucket already exists.");
        } else {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        }
        String originalFilename = file.getOriginalFilename();
        //拼接生成新的UUID形式的文件名
        String objectName = new SimpleDateFormat("yyyy/MM/dd/").format(new Date()) +
                UUID.randomUUID().toString().replaceAll("-", "")
                + originalFilename.substring(originalFilename.lastIndexOf("."));
 
        PutObjectArgs objectArgs = PutObjectArgs.builder().object(objectName)
                .bucket(bucketName)
                .contentType(file.getContentType())
                .stream(file.getInputStream(), file.getSize(), -1).build();
        minioClient.putObject(objectArgs);
        //組裝桶中文件的訪問url
        String resUrl = endpoint + "/" + bucketName + "/" + objectName;
        return resUrl;
    }
 
    /**
     * 刪除文件
     *
     * @param pathUrl 文件全路徑
     */
    @Override
    public void delete(String pathUrl) {
        String key = pathUrl.replace(minIOConfigProperties.getEndpoint() + "/", "");
        int index = key.indexOf(separator);
        String bucket = key.substring(0, index);
        String filePath = key.substring(index + 1);
        // 刪除Objects
        RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucket).object(filePath).build();
        try {
            minioClient.removeObject(removeObjectArgs);
        } catch (Exception e) {
            log.error("minio remove file error.  pathUrl:{}", pathUrl);
            e.printStackTrace();
        }
    }
 
    public List<Bucket> listBuckets()
            throws Exception {
        return minioClient.listBuckets();
    }
 
    public boolean bucketExists(String bucketName) throws Exception {
        boolean flag = minioClient.bucketExists(bucketName);
        if (flag) {
            return true;
        }
        return false;
    }
 
    @Override
    public List<String> listBucketNames() throws Exception{
        List<Bucket> bucketList = listBuckets();
        List<String> bucketListName = new ArrayList<>();
        for (Bucket bucket : bucketList) {
            bucketListName.add(bucket.name());
        }
        return bucketListName;
    }
 
    @Override
    public boolean makeBucket(String bucketName) throws Exception{
        boolean flag = bucketExists(bucketName);
        if (!flag) {
            minioClient.makeBucket(bucketName);
            return true;
        } else {
            return false;
        }
    }
 
    @Override
    public boolean removeBucket(String bucketName) throws Exception{
        boolean flag = bucketExists(bucketName);
        if (flag) {
            Iterable<Result<Item>> myObjects = listObjects(bucketName);
            for (Result<Item> result : myObjects) {
                Item item = result.get();
                // 有對象文件,則刪除失敗
                if (item.size() > 0) {
                    return false;
                }
            }
            // 刪除存儲桶,注意,只有存儲桶為空時才能刪除成功。
            minioClient.removeBucket(bucketName);
            flag = bucketExists(bucketName);
            if (!flag) {
                return true;
            }
 
        }
        return false;
    }
 
    @Override
    public List<String> listObjectNames(String bucketName) throws Exception{
        List<String> listObjectNames = new ArrayList<>();
        boolean flag = bucketExists(bucketName);
        if (flag) {
            Iterable<Result<Item>> myObjects = listObjects(bucketName);
            for (Result<Item> result : myObjects) {
                Item item = result.get();
                listObjectNames.add(item.objectName());
            }
        }
        return listObjectNames;
    }
 
    @Override
    public boolean removeObject(String bucketName, String objectName) throws Exception{
        boolean flag = bucketExists(bucketName);
        if (flag) {
            List<String> objectList = listObjectNames(bucketName);
            for (String s : objectList) {
                if(s.equals(objectName)){
                    minioClient.removeObject(bucketName, objectName);
                    return true;
                }
            }
        }
        return false;
    }
 
    @Override
    public String getObjectUrl(String bucketName, String objectName) throws Exception{
        boolean flag = bucketExists(bucketName);
        String url = "";
        if (flag) {
            url = minioClient.getObjectUrl(bucketName, objectName);
        }
        return url;
    }
 
    public Iterable<Result<Item>> listObjects(String bucketName) throws Exception {
        boolean flag = bucketExists(bucketName);
        if (flag) {
            return minioClient.listObjects(bucketName);
        }
        return null;
    }
 
 
}

5.2.4 編寫測試接口

為了方便測試,下面定義了一個測試接口

 
import com.congge.service.MinioFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
 
import javax.servlet.http.HttpServletResponse;
import java.util.List;
 
@RestController
@Slf4j
public class FileController {
 
    @Autowired
    private MinioFileService minioFileService;
 
    /**
     * 上傳文件
     * @param file
     * @return
     * @throws Exception
     */
    @PostMapping("/upload")
    public String upload(@RequestBody MultipartFile file) throws Exception {
        String url = minioFileService.uploadFile(file);
        return "文件上傳成功,文件路徑:" + url;
    }
 
    /**
     * 下載文件
     * @param pathUrl
     * @param response
     */
    @GetMapping("/download")
    public void download(@RequestParam("pathUrl") String pathUrl, HttpServletResponse response) {
        minioFileService.downLoadFile(pathUrl,response);
    }
 
    /**
     * 列出所有bucket名稱
     * @return
     * @throws Exception
     */
    @PostMapping("/list/bucket")
    public List<String> list() throws Exception {
        return minioFileService.listBucketNames();
    }
 
 
    /**
     * 創(chuàng)建bucket
     * @param bucketName
     * @return
     * @throws Exception
     */
    @PostMapping("/create/bucket")
    public boolean createBucket(@RequestParam("bucketName")String bucketName) throws Exception {
        return minioFileService.makeBucket(bucketName);
    }
 
    /**
     * 刪除bucket
     * @param bucketName
     * @return
     * @throws Exception
     */
    @PostMapping("/delete/bucket")
    public boolean deleteBucket(@RequestParam("bucketName")String bucketName) throws Exception {
        return minioFileService.removeBucket(bucketName);
    }
 
    /**
     * 列出bucket的所有對象名稱
     * @param bucketName
     * @return
     * @throws Exception
     */
    @PostMapping("/list/object_names")
    public List<String> listObjectNames(@RequestParam("bucketName")String bucketName) throws Exception {
        return minioFileService.listObjectNames(bucketName);
    }
 
    /**
     * 刪除bucket中的某個對象
     * @param bucketName
     * @param objectName
     * @return
     * @throws Exception
     */
    @PostMapping("/remove/object")
    public boolean removeObject(@RequestParam("bucketName")String bucketName,@RequestParam("objectName") String objectName) throws Exception {
        return minioFileService.removeObject(bucketName, objectName);
    }
 
    /**
     * 獲取文件訪問路徑
     * @param bucketName
     * @param objectName
     * @return
     * @throws Exception
     */
    @PostMapping("/get/object/url")
    public String getObjectUrl(@RequestParam("bucketName")String bucketName, @RequestParam("objectName")String objectName) throws Exception {
        return minioFileService.getObjectUrl(bucketName, objectName);
    }
 
}

5.2.5 接口測試

上傳文件測試

上傳成功后,返回了文件的完整路徑,方便后續(xù)使用

然后在控制臺的test這個bucket中檢查是否上傳上去了

下載文件測試

使用上一步返回的url,直接調(diào)用下載接口,下載完成后可以直接預(yù)覽

更多的接口有興趣的同學(xué)可以一一嘗試下,就不再贅述了。

六、寫在文末

本文詳細(xì)總結(jié)了Minio的搭建使用,以及與springboot整合的完整步驟,作為一款適用且輕量級的文件存儲服務(wù)器,可以私有化部署,也可以很方便進(jìn)行云上部署、容器化部署,為今后在實(shí)際項(xiàng)目中的技術(shù)選型提供一個參考,本篇到此結(jié)束,感謝觀看。

以上就是springboot整合minio的超詳細(xì)教程的詳細(xì)內(nèi)容,更多關(guān)于springboot整合minio的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Springboot?手動分頁查詢分批批量插入數(shù)據(jù)的實(shí)現(xiàn)流程

    Springboot?手動分頁查詢分批批量插入數(shù)據(jù)的實(shí)現(xiàn)流程

    這篇文章主要介紹了Springboot?手動分頁查詢分批批量插入數(shù)據(jù)的實(shí)現(xiàn)流程,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • Java虛擬機(jī)JVM類加載機(jī)制(從類文件到虛擬機(jī))

    Java虛擬機(jī)JVM類加載機(jī)制(從類文件到虛擬機(jī))

    所謂的類加載機(jī)制就是虛擬機(jī)將class文件加載到內(nèi)存,并對數(shù)據(jù)進(jìn)行驗(yàn)證,轉(zhuǎn)換解析和初始化,形成虛擬機(jī)可以直接使用的java類型,本文給大家介紹類加載機(jī)制過程從類文件到虛擬機(jī)的詳細(xì)說明,感興趣的朋友跟隨小編一起看看吧
    2021-06-06
  • springboot使用JPA時間類型進(jìn)行模糊查詢的方法

    springboot使用JPA時間類型進(jìn)行模糊查詢的方法

    這篇文章主要介紹了springboot使用JPA時間類型進(jìn)行模糊查詢的方法,需要的朋友可以參考下
    2018-03-03
  • 解決maven加載依賴時遇到的問題

    解決maven加載依賴時遇到的問題

    這篇文章主要介紹了解決maven加載依賴時遇到的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Java編程中的4種代碼塊詳解

    Java編程中的4種代碼塊詳解

    在本篇內(nèi)容里小編個總結(jié)了Java編程中的4種代碼塊相關(guān)的知識點(diǎn),有興趣的朋友們可以學(xué)習(xí)下。
    2021-06-06
  • springboot實(shí)現(xiàn)小程序支付的項(xiàng)目實(shí)踐

    springboot實(shí)現(xiàn)小程序支付的項(xiàng)目實(shí)踐

    本文主要介紹了springboot實(shí)現(xiàn)小程序支付的項(xiàng)目實(shí)踐,?可以通過調(diào)用微信支付?API?實(shí)現(xiàn)支付功能,具有一定的參考價值,感興趣的可以了解一下
    2023-09-09
  • Zookeeper原理及在Dubbo中的使用示例詳解

    Zookeeper原理及在Dubbo中的使用示例詳解

    這篇文章主要為大家介紹了Zookeeper原理及在Dubbo中的使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Java png圖片修改像素rgba值的操作

    Java png圖片修改像素rgba值的操作

    這篇文章主要介紹了Java png圖片修改像素rgba值的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Mybatis-Plus的應(yīng)用場景描述及注入SQL原理分析

    Mybatis-Plus的應(yīng)用場景描述及注入SQL原理分析

    MyBatis-Plus是一個 MyBatis 的增強(qiáng)工具,在 MyBatis 的基礎(chǔ)上只做增強(qiáng)不做改變,為簡化開發(fā)、提高效率而生,本文重點(diǎn)給大家介紹Mybatis-Plus的應(yīng)用場景及注入SQL原理分析,感興趣的朋友跟隨小編一起學(xué)習(xí)吧
    2021-05-05
  • SpringMVC處理數(shù)據(jù)輸出的實(shí)例代碼

    SpringMVC處理數(shù)據(jù)輸出的實(shí)例代碼

    這篇文章主要給大家介紹了關(guān)于SpringMVC處理數(shù)據(jù)輸出的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05

最新評論