Maison > Java > javaDidacticiel > le corps du texte

Comment SpringBoot utilise Minio pour le stockage de fichiers

WBOY
Libérer: 2023-05-11 12:16:05
avant
1570 Les gens l'ont consulté

1. minio

MinIO est une solution de stockage d'objets hautes performances qui prend en charge nativement le déploiement Kubernetes. MinIO fournit une API compatible avec Amazon Web Services S3 et prend en charge toutes les fonctionnalités de base S3. MinIO 是一个高性能的对象存储原生支持 Kubernetes 部署的解决方案。 MinIO 提供了一个 Amazon Web Services S3 兼容 API 并支持所有核心 S3 功能。

MinIO 对象存储使用 buckets 来组织对象。 存储桶类似于文件系统中的文件夹或目录,其中每个 桶可以容纳任意数量的对象。 MinIO 存储桶提供 与 AWS S3 存储桶相同的功能。

其中 MinIO 的优势有:

高性能:

MinIO是全球领先的对象存储先锋,在标准硬件上,读/写速度上高达183 GB / 秒171 GB / 秒

可扩展性:

MinIO利用了web缩放器的来之不易的知识,为对象存储带来了简单的存储缩放模型, 在 MinIO, 扩展从单个群集开始,该群集可以与其他MinIO群集联合以创建全局名称空间, 并在需要时可以跨越多个不同的数据中心。 通过添加更多集群可以扩展名称空间, 更多机架,直到实现目标。

云原生支持:

MinIO 是在过去4年的时间内从0开始打造的一款软件 ,符合一切原生云计算的架构和构建过程,并且包含最新的云计算的全新的技术和概念。 其中包括支持Kubernetes 、微服和多租户的的容器技术。使对象存储对于 Kubernetes更加友好。

源码开放与企业级支持:

MinIO 基于Apache V2 license 100% 开放源代码 。 这就意味着 MinIO的客户能够自动的、无限制、自由免费使用和集成MinIO、自由的创新和创造、 自由的去修改、自由的再次发行新的版本和软件. 确实, MinIO 强有力的支持和驱动了很多世界500强的企业。 此外,其部署的多样性和专业性提供了其他软件无法比拟的优势。

在实验开始前请确保安装完成了 minio

Comment SpringBoot utilise Minio pour le stockage de fichiers

二、SpringBoot 使用 Minio 进行文件存储

首先新建一个 SpringBoot 项目,在 pom 中引入 minio 依赖:

<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.2.1</version>
</dependency>
Copier après la connexion

在配置文件中,声明出 minio 的信息:

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

下面创建一个配置类,对 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;
    }
}
Copier après la connexion

下面创建一个工具类 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();
    }

}
Copier après la connexion
Copier après la connexion

编写测试接口,进行测试:

@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();
    }

}
Copier après la connexion
Copier après la connexion

三、测试

测试上传文件:

Comment SpringBoot utilise Minio pour le stockage de fichiers

如果使用 返回的 url 直接访问文件,可以发现返回权限不足:

Comment SpringBoot utilise Minio pour le stockage de fichiers

这里需要改一下 BucketAccess Policy ,默认为 private,可以修改为 public 便无需认证,但安全性无法保证:

Comment SpringBoot utilise Minio pour le stockage de fichiers

Comment SpringBoot utilise Minio pour le stockage de fichiers

Comment SpringBoot utilise Minio pour le stockage de fichiers

再次进行访问,文件就可以打开了:

Comment SpringBoot utilise Minio pour le stockage de fichiers

如果需要保持 private ,可以通过 MinioClient 进行下载,使用 download 测试接口下载文件:http://localhost:8080/file/download/20cab4e3979eba6003f95aca0dc75c63.jpg

Le stockage d'objets MinIO utilise des buckets pour organiser les objets. Les compartiments sont similaires aux dossiers ou répertoires d'un système de fichiers, où chaque compartiment peut contenir n'importe quel nombre d'objets. Le compartiment MinIO fournit les mêmes fonctionnalités que le compartiment AWS S3.

Comment SpringBoot utilise Minio pour le stockage de fichiersLes avantages de MinIO sont :

🎜Hautes performances : 🎜🎜MinIO est le premier pionnier mondial du stockage d'objets sur du matériel standard, Read. /write à des vitesses allant jusqu'à 183 Go/sec et 171 Go/sec. 🎜🎜Évolutivité :🎜🎜MinIO exploite les connaissances durement acquises des scalers web pour simplifier le stockage objet. Modèle de mise à l'échelle du stockage, dans MinIO, la mise à l'échelle commence à partir d'un seul cluster, qui peut être fédéré avec d'autres clusters MinIO pour créer un espace de noms global, et peut s'étendre sur plusieurs clusters différents si nécessaire pour les centres de données. L'espace de noms peut être étendu en ajoutant plus de clusters, plus de racks, jusqu'à ce que l'objectif soit atteint. 🎜🎜Support natif du cloud :🎜🎜MinIO est un logiciel construit à partir de zéro au cours des 4 dernières années, conforme à l'architecture et au processus de construction de tout le cloud computing natif, et contient les dernières nouvelles technologies et concepts de cloud computing. Cela inclut la technologie de conteneur qui prend en charge Kubernetes, les microservices et la multilocation. Rendre le stockage d'objets plus convivial pour Kubernetes. 🎜🎜Support Open source et niveau entreprise :🎜🎜MinIO est basé sur la Licence Apache V2 100% open source. Cela signifie que les clients de MinIO peuvent automatiquement, sans restriction et librement utiliser et intégrer MinIO, innover et créer librement, modifier librement et redistribuer librement de nouvelles versions et logiciels. MinIO a fortement soutenu et dirigé de nombreuses entreprises Fortune 500. De plus, la diversité et le professionnalisme de son déploiement offrent des avantages que d’autres logiciels ne peuvent égaler. 🎜🎜Veuillez vous assurer que l'installation de minio est terminée avant de commencer l'expérience : 🎜🎜Comment SpringBoot utilise Minio pour le stockage de fichiers🎜🎜2. SpringBoot utilise Minio pour le stockage de fichiers🎜🎜Créez d'abord un nouveau projet SpringBoot et introduisez-le dans pom minio dépend de : 🎜rrreee🎜Dans le fichier de configuration, déclarez les informations de minio : 🎜rrreee🎜Créez une classe de configuration ci-dessous pour effectuer MinioClient Créer : 🎜rrreee🎜 Créez une classe d'outils MinioTool ci-dessous et encapsulez les opérations courantes dans la classe d'outils : 🎜rrreee🎜Écrivez une interface de test et testez-la : 🎜rrreee🎜 3. Testez 🎜 🎜Test de fichiers de téléchargement : 🎜🎜Comment SpringBoot utilise-t-il Minio pour le stockage de fichiers 🎜🎜Si vous utilisez l'URL renvoyée lorsque vous accédez directement au fichier, vous pouvez constater que l'autorisation de retour est insuffisante : 🎜🎜Comment utiliser Minio pour le stockage de fichiers SpringBoot🎜🎜Ici, vous devez modifier la Politique d'accès de Bucket. La valeur par défaut est private, qui peut être modifié en public code> Aucune authentification n'est requise, mais la sécurité ne peut être garantie : 🎜🎜<img src="https://img.php.cn/upload%20/article/000/887/227/168377857086128.jpg" alt="Comment utiliser Minio avec le stockage de fichiers SpringBoot">🎜🎜<img src="https://img.php.cn/upload/article/000/%20887/227/168377857019765.jpg" alt="Comment SpringBoot utilise Minio pour le stockage de fichiers"> 🎜🎜<img src="https://img.php.cn/upload/article/000/887/227/168377857057222%20.jpg" alt="Comment SpringBoot utilise Minio pour le stockage de fichiers">🎜🎜Visitez à nouveau, le fichier peut être ouvert : 🎜🎜<img src="https://img.php.cn/upload/article/000/%20887/227/168377857057448.jpg" alt="Comment SpringBoot utilise-t-il Minio pour le stockage de fichiers"> 🎜🎜Si vous devez garder <code>privé, vous pouvez télécharger via MinioClient et utilisez l'interface de test download pour télécharger le fichier : http://localhost: 8080/file/download/20cab4e3979eba6003f95aca0dc75c63.jpg🎜🎜🎜🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!