ホームページ  >  記事  >  Java  >  SpringBoot がファイル ストレージに Minio を使用する方法

SpringBoot がファイル ストレージに Minio を使用する方法

WBOY
WBOY転載
2023-05-11 12:16:051671ブラウズ

1. minio

MinIO は、Kubernetes デプロイメントをネイティブにサポートする高性能オブジェクト ストレージ ソリューションです。 MinIO は、API と互換性があり、すべてのコア S3 機能をサポートする Amazon Web Services S3 を提供します。

MinIO オブジェクト ストレージは、buckets を使用してオブジェクトを整理します。バケットはファイル システムのフォルダーまたはディレクトリに似ており、各バケットには任意の数のオブジェクトを保持できます。 MinIO バケットは、AWS S3 バケットと同じ機能を提供します。

MinIO の利点は次のとおりです:

高パフォーマンス:

MinIO は世界をリードしています。オブジェクト ストレージのパイオニアであり、標準ハードウェアで最大 183 GB/秒 および 171 GB/秒の読み取り/書き込み速度を実現します。

スケーラビリティ:

MinIO は、web スケーラーの苦労して得た知識を活用して、オブジェクト ストレージに最適なソリューションを提供します。 MinIO では、シンプルなストレージ スケーリング モデルを導入し、スケーリングは単一のクラスターから開始され、他の MinIO クラスターとフェデレートしてグローバル名前空間を作成し、必要に応じて複数の異なるクラスターにまたがることができます。データセンター。目標が達成されるまで、クラスターやラックを追加することで名前空間を拡張できます。

クラウド ネイティブ サポート:

MinIO は、過去 4 年間にゼロから構築されたソフトウェアであり、すべてのネイティブ クラウド コンピューティング アーキテクチャと一致しています。および構築プロセスには、最新のクラウド コンピューティングの新しいテクノロジと概念が含まれています。これには、Kubernetes、マイクロサービス、マルチテナンシーをサポートするコンテナー テクノロジーが含まれます。オブジェクト ストレージを Kubernetes にとってより使いやすいものにします。

オープン ソース コードとエンタープライズ レベルのサポート:

MinIO Apache V2 ライセンス 100% オープン ソース コードに基づく。これは、MinIO の顧客が自動的に、制限なく、自由に MinIO を使用および統合し、自由に革新および作成し、自由に変更し、新しいバージョンとソフトウェアを自由に再リリースできることを意味します。 , MinIO は、多くのフォーチュン 500 企業を強力にサポートし、推進してきました。さらに、その導入の多様性と専門性により、他のソフトウェアでは真似できない利点が得られます。

実験を開始する前にインストールが完了していることを確認してください

minio:

SpringBoot がファイル ストレージに Minio を使用する方法

#2. SpringBoot はファイル ストレージに Minio を使用します

まず、新しい

SpringBoot プロジェクトを作成し、minio 依存関係を pom に導入します:

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

構成ファイルで、

を宣言します。 minio に関する情報:

minio:
  url: http://192.168.40.169:9000   # minio配置的地址,端口9000,注意不是控制台的端口
  accessKey: minioadmin   # 账号
  secretKey: minioadmin   # 密码
  bucketName: test-bucket  # MinIO桶名字

以下の構成クラスを作成して、

MinioClient:

@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
    /**
     * 服务地址
     */
    private String url;
 
    /**
     * 用户名
     */
    private String accessKey;
 
    /**
     * 密码
     */
    private String secretKey;
 
    /**
     * 存储桶名称
     */
    private String bucketName;

    @Bean
    public MinioClient getMinioClient() throws Exception {
        MinioClient minioClient = MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();
        //判断桶是否存在,不存在则新建
        if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())){
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        }
        return minioClient;
    }
}

以下にツール クラスを作成します。

MinioTool 共通にカプセル化します。ツール クラスで使用される操作:

@Component
public class MinioTool {
    
    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioConfig minioConfig;
 
    /**
     * 查看存储bucket是否存在
     *
     * @param bucketName 存储bucket
     * @return boolean
     */
    public Boolean bucketExists(String bucketName) {
        Boolean found;
        try {
            found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return found;
    }
 
    /**
     * 创建存储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;
    }

    /**
     * 查看文件对象
     *
     * @param bucketName 存储bucket名称
     * @return 存储bucket内文件对象信息
     */
    public Iterable<Result<Item>> listObjects(String bucketName) {
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).build());
        return results;
    }

    /**
     * 批量删除文件对象
     *
     * @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;
    }


    /**
     * 文件上传
     * 文件名称相同会覆盖
     * @param file       文件
     * @return Boolean
     */
    public Boolean upload(MultipartFile file, String fileName) {
        try {
            if (!bucketExists(minioConfig.getBucketName())) {
                makeBucket(minioConfig.getBucketName());
            }
            PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(minioConfig.getBucketName()).object(fileName)
                    .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
            minioClient.putObject(objectArgs);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
 
    /**
     * 文件下载
     *
     * @param fileName   文件名称
     * @param res        response
     * @return Boolean
     */
    public void download(String fileName, HttpServletResponse res) {
        GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(minioConfig.getBucketName())
                .object(fileName).build();
        try (GetObjectResponse response = minioClient.getObject(objectArgs)) {
            byte[] buf = new byte[1024];
            int len;
            try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()) {
                while ((len = response.read(buf)) != -1) {
                    os.write(buf, 0, len);
                }
                os.flush();
                byte[] bytes = os.toByteArray();
                res.setCharacterEncoding("utf-8");
                //设置强制下载不打开
                res.setContentType("application/force-download");
                res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
                try (ServletOutputStream stream = res.getOutputStream()) {
                    stream.write(bytes);
                    stream.flush();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String getFileUrl(String fileName){
        return StringFormatter.concat(minioConfig.getUrl(), "/", minioConfig.getBucketName(), "/", fileName).getValue();
    }

}

テスト インターフェイスを作成してテスト:

@Component
public class MinioTool {
    
    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioConfig minioConfig;
 
    /**
     * 查看存储bucket是否存在
     *
     * @param bucketName 存储bucket
     * @return boolean
     */
    public Boolean bucketExists(String bucketName) {
        Boolean found;
        try {
            found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return found;
    }
 
    /**
     * 创建存储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;
    }

    /**
     * 查看文件对象
     *
     * @param bucketName 存储bucket名称
     * @return 存储bucket内文件对象信息
     */
    public Iterable<Result<Item>> listObjects(String bucketName) {
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).build());
        return results;
    }

    /**
     * 批量删除文件对象
     *
     * @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;
    }


    /**
     * 文件上传
     * 文件名称相同会覆盖
     * @param file       文件
     * @return Boolean
     */
    public Boolean upload(MultipartFile file, String fileName) {
        try {
            if (!bucketExists(minioConfig.getBucketName())) {
                makeBucket(minioConfig.getBucketName());
            }
            PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(minioConfig.getBucketName()).object(fileName)
                    .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
            minioClient.putObject(objectArgs);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
 
    /**
     * 文件下载
     *
     * @param fileName   文件名称
     * @param res        response
     * @return Boolean
     */
    public void download(String fileName, HttpServletResponse res) {
        GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(minioConfig.getBucketName())
                .object(fileName).build();
        try (GetObjectResponse response = minioClient.getObject(objectArgs)) {
            byte[] buf = new byte[1024];
            int len;
            try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()) {
                while ((len = response.read(buf)) != -1) {
                    os.write(buf, 0, len);
                }
                os.flush();
                byte[] bytes = os.toByteArray();
                res.setCharacterEncoding("utf-8");
                //设置强制下载不打开
                res.setContentType("application/force-download");
                res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
                try (ServletOutputStream stream = res.getOutputStream()) {
                    stream.write(bytes);
                    stream.flush();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String getFileUrl(String fileName){
        return StringFormatter.concat(minioConfig.getUrl(), "/", minioConfig.getBucketName(), "/", fileName).getValue();
    }

}

3. テスト

テスト アップロード ファイル:

SpringBoot がファイル ストレージに Minio を使用する方法

返された URL を使用してファイルに直接アクセスすると、戻る権限が不十分であることがわかります:

SpringBoot がファイル ストレージに Minio を使用する方法

ここで変更する必要があります

バケット アクセス ポリシーのデフォルトはprivateであり、認証なしでpublicに変更できますが、セキュリティは保証できません:

SpringBoot がファイル ストレージに Minio を使用する方法

SpringBoot がファイル ストレージに Minio を使用する方法

SpringBoot がファイル ストレージに Minio を使用する方法

#もう一度アクセスすると、ファイルを開くことができます:

SpringBoot がファイル ストレージに Minio を使用する方法

必要に応じて、

プライベートを保持し、MinioClientを通じてダウンロードできます。downloadテストインターフェイスを使用してファイルをダウンロードします: http://localhost:8080/ファイル/ダウンロード/20cab4e3979eba6003f95aca0dc75c63 .jpg

SpringBoot がファイル ストレージに Minio を使用する方法

以上がSpringBoot がファイル ストレージに Minio を使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。