Java 集成 MinIO


配置类

package com.seliote.mlb.fs.config;

import com.seliote.mlb.common.config.PropertiesInjector;
import io.minio.BucketExistsArgs;
import io.minio.MinioClient;
import io.minio.errors.MinioException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * MinIO 配置类
 *
 * @author seliote
 */
@Slf4j
@Configuration
public class MinioConfig {

    private final PropertiesInjector.Minio minioProp;

    @Autowired
    public MinioConfig(PropertiesInjector propertiesInjector) {
        this.minioProp = propertiesInjector.getMinio();
    }

    /**
     * MinioClient Bean
     *
     * @return MinioClient 对象
     */
    @Bean
    public MinioClient minioClient()
            throws MinioException, IOException, NoSuchAlgorithmException, InvalidKeyException {
        var client = MinioClient.builder()
                .endpoint(minioProp.getEndpoint())
                .credentials(minioProp.getAccessKey(), minioProp.getSecretKey())
                .build();
        // 检查 Bucket 是否存在
        boolean found = client.bucketExists(BucketExistsArgs.builder()
                .bucket(minioProp.getBucket())
                .build());
        if (!found) {
            log.error("Bucket {} not found! Please create it first", minioProp.getBucket());
            throw new IllegalStateException("Bucket not found");
        }
        log.info("Minio bucket: {}", minioProp.getBucket());
        return client;
    }
}

Service,这里是文件都不会很大的情况,为了避免不经意的句柄泄漏所以都采取了 byte[] 类型,可根据需要改为流

package com.seliote.mlb.fs.service;

import com.seliote.mlb.common.jsr303.minio.Catalog;
import com.seliote.mlb.common.jsr303.minio.Extension;
import com.seliote.mlb.common.jsr303.minio.Filename;
import com.seliote.mlb.fs.exception.MinioException;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotNull;

/**
 * Minio Service
 *
 * @author seliote
 * @version 2021-07-02
 */
@Validated
public interface MinioService {

    /**
     * 上传文件
     *
     * @param catalog   文件分类
     * @param extension 文件类型
     * @param bytes     输入字节
     * @return 上传文件返回的名称
     * @throws MinioException 上传失败时抛出
     */
    @Filename
    String upload(@Catalog String catalog, @Extension String extension, @NotNull byte[] bytes)
            throws MinioException;

    /**
     * 下载文件
     *
     * @param catalog  文件分类
     * @param filename 上传文件返回的名称
     * @return 文件字节数组
     * @throws MinioException 下载失败时抛出
     */
    @NotNull
    byte[] download(@Catalog String catalog, @Filename String filename) throws MinioException;
}

Impl

package com.seliote.mlb.fs.service.impl;

import com.seliote.mlb.common.config.YmlConfig;
import com.seliote.mlb.fs.exception.MinioException;
import com.seliote.mlb.fs.service.MinioService;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

/**
 * Minio Service 实现
 *
 * @author seliote
 * @version 2021-07-02
 */
@Slf4j
@Service
public class MinioServiceImpl implements MinioService {

    // Minio 路径分隔符
    private static final String MINIO_PATH_SEPARATOR = "/";

    private final YmlConfig.Minio minio;
    private final MinioClient minioClient;

    @Autowired
    public MinioServiceImpl(YmlConfig ymlConfig, MinioClient minioClient) {
        this.minio = ymlConfig.getMinio();
        this.minioClient = minioClient;
    }

    @Override
    public String upload(String catalog, String extension, byte[] bytes) throws MinioException {
        String filename = UUID.randomUUID().toString();
        // 分为 26 * 26 目录存储,避免同级存在大量文件
        String path = catalog + MINIO_PATH_SEPARATOR + filename.charAt(0) + MINIO_PATH_SEPARATOR
                + filename.charAt(1) + MINIO_PATH_SEPARATOR + filename + "." + extension;
        try (var is = new ByteArrayInputStream(bytes)) {
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(minio.getBucket())
                    .object(path)
                    .stream(is, -1, 1024 * 1024 * 10)
                    .build());
            log.info("Upload file {}", path);
            return filename;
        } catch (io.minio.errors.MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException
                exception) {
            log.info("Failed upload file {}, {}", filename, exception.getMessage());
            throw new MinioException(exception);
        }
    }

    @Override
    public byte[] download(String catalog, String filename) throws MinioException {
        String path = catalog + MINIO_PATH_SEPARATOR + filename.charAt(0) + MINIO_PATH_SEPARATOR
                + filename.charAt(1) + MINIO_PATH_SEPARATOR + filename;
        try (var is = minioClient.getObject(GetObjectArgs.builder()
                .bucket(minio.getBucket())
                .object(path)
                .build())) {
            log.info("Download file {}", path);
            return is.readAllBytes();
        } catch (io.minio.errors.MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException
                exception) {
            log.info("Failed download file {}, {}", path, exception.getMessage());
            throw new MinioException(exception);
        }
    }
}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM