springboot3.5.8整合minio8.5.9

不知道为什么使用minio自带的okhttp总是报错找不到mino。所以我依赖了okhttp,因为我这个minio使用docker部署的版本比较高是社区版,所以我在代码中创建桶设置了访问策略,要不然默认是private。

java项目pom.xml文件添加依赖:

复制代码
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.11.0</version>
        </dependency>

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

添加config

复制代码
package com.test.config.minio;

import io.minio.MinioClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {

    /**
     * 连接地址
     */
    private String endpoint;
    /**
     * 用户名
     */
    private String accessKey;
    /**
     * 密码
     */
    private String secretKey;

    private String bucketName;

    @Bean
    public MinioClient minioClient() {

        return MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();
    }

}

application.yml配置

复制代码
minio:
  endpoint: http://127.0.0.1:9000        #MinIO资源地址
  accessKey: minioadmin                  #访问key
  secretKey: minioadmin                  #访问密钥
  bucketName: test                       #存储桶名称
  # 对外访问前缀
  public-url-prefix: http://127.0.0.1:9000/test

util工具类

复制代码
package com.test.common.util;


import com.nuctech.ims.config.minio.MinioConfig;
import io.minio.*;
import io.minio.http.Method;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

import static cn.dev33.satoken.SaManager.log;

@Component
public class MinioUtil {


    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioConfig minioConfig;

    /**
     * 创建存储bucket
     *
     * @param bucketName 存储bucket名称
     * @return Boolean
     */
    public boolean makeBucket(String bucketName) {
        try {
            // 1. 创建 bucket
            boolean exists = minioClient.bucketExists(
                    BucketExistsArgs.builder().bucket(bucketName).build());

            if (!exists) {
                minioClient.makeBucket(
                        MakeBucketArgs.builder().bucket(bucketName).build());
            }

            // 2. 设置为 public 访问
            String policy = buildPublicReadPolicy(bucketName);

            minioClient.setBucketPolicy(
                    SetBucketPolicyArgs.builder()
                            .bucket(bucketName)
                            .config(policy)
                            .build());

            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    /**
     * 删除存储bucket
     *
     * @param bucketName 存储bucket名称
     * @return Boolean
     */
    public boolean removeBucket(String bucketName) {

        try {

            minioClient.removeBucket(RemoveBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
            return true;
        } catch (Exception e) {

            e.printStackTrace();
        }
        return false;
    }

    private String buildPublicReadPolicy(String bucketName) {
        return "{\n" +
                "  \"Version\": \"2012-10-17\",\n" +
                "  \"Statement\": [\n" +
                "    {\n" +
                "      \"Effect\": \"Allow\",\n" +
                "      \"Principal\": \"*\",\n" +
                "      \"Action\": [\"s3:GetObject\"],\n" +
                "      \"Resource\": [\"arn:aws:s3:::" + bucketName + "/*\"]\n" +
                "    }\n" +
                "  ]\n" +
                "}";
    }


    /**
     * 查看存储bucket是否存在
     *
     * @param bucketName
     * @return
     */
    public boolean bucketExists(String bucketName) {

        try {

            return minioClient.bucketExists(BucketExistsArgs
                    .builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {

            e.printStackTrace();
        }
        return false;
    }

    /**
     * 文件上传
     *
     * @param file       文件
     * @return
     */
    public String uploadFile(MultipartFile file) {

        try {
            if (file == null || file.getSize() == 0) {
                log.error("上传文件异常:文件大小为空");
                throw new RuntimeException("文件大小不能为空");
            }
            //文件的原始名称
            String originalFilename = file.getOriginalFilename();
            //文件的ContentType
            String contentType = file.getContentType();
            // 生成存储对象的名称(将 UUID 字符串中的 - 替换成空字符串)
            String key = UUID.randomUUID().toString().replace("-", "");
            // 获取文件的后缀,如 .jpg
            String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
            // 拼接上文件后缀,即为要存储的文件名
            //拼写图片路径
            //拼写图片路径
            String fileName = new SimpleDateFormat("yyyy/MM/dd").format(new Date())
                    +"/"+ UUID.randomUUID().toString()+originalFilename.substring(originalFilename.lastIndexOf("."));

//        String fileName = String.format("%s%s", key, suffix);
            // 上传文件至 Minio
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(fileName)
                    .stream(file.getInputStream(), file.getSize(), -1)
                    .contentType(contentType)
                    .build());
            // 返回文件的访问链接
            String url = String.format("%s/%s/%s", minioConfig.getEndpoint(), minioConfig.getBucketName(), fileName);
            return url;
        } catch (Exception e) {

            e.printStackTrace();
        }
        return "";
    }

    /**
     * 获取对象url
     *
     * @param objectName 对象名称
     * @return
     */
    public String getObjectUrl(String objectName) {

        try {

            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .method(Method.GET)
                    .bucket(minioConfig.getBucketName())
                    .object(objectName)
                    .build());
        } catch (Exception e) {

            e.printStackTrace();
        }
        return null;
    }

}

controller

复制代码
package com.test.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import com.nuctech.ims.common.model.Result;
import com.nuctech.ims.common.util.MinioUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import static cn.dev33.satoken.SaManager.log;

@SaCheckLogin
@RestController
@RequestMapping("/file")
public class FileController {

    @Autowired
    private MinioUtil minioUtil;

    /**
     * 创建存储bucket
     *
     * @param bucketName
     * @return
     */
    @PostMapping("makeBucket")
    public Result<Void> makeBucket(String bucketName) {

        boolean success = minioUtil.makeBucket(bucketName);
        return Result.success();
    }

    /**
     * 删除存储bucket
     *
     * @param bucketName
     * @return
     */
    @PostMapping("removeBucket")
    public Result<Void> removeBucket(String bucketName) {

        boolean success = minioUtil.removeBucket(bucketName);
        return Result.success();
    }

    /**
     * 查看存储bucket是否存在
     *
     * @param bucketName
     * @return
     */
    @GetMapping("bucketExists")
    public Result<Void> bucketExists(String bucketName) {
        boolean success = minioUtil.bucketExists(bucketName);
        return Result.success();
    }

    /**
     * 文件上传
     *
     * @param file
     * @return
     */
    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Result<String> uploadFile(@RequestParam("file") MultipartFile file) {

        try {
            // 上传文件
            String url = minioUtil.uploadFile(file);
            // 构建成功返参,将图片的访问链接返回
            return Result.success(url);
        } catch (Exception e) {
            // 手动抛出业务异常,提示 "文件上传失败"
            log.error("文件上传失败:{}", file);
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取对象url
     *
     * @param objectName
     * @return
     */
    @GetMapping("getObjectUrl")
    public Result<String> getObjectUrl(String objectName) {
        String fileUrl = minioUtil.getObjectUrl(objectName);
        return Result.success(fileUrl);
    }
}
相关推荐
不知道累,只知道类14 小时前
深入理解 Java 虚拟线程 (Project Loom)
java·开发语言
myzshare14 小时前
实战分享:我是如何用SSM框架开发出一个完整项目的
java·mysql·spring cloud·微信小程序
Chan1614 小时前
【 Java八股文面试 | JavaSE篇 】
java·jvm·spring boot·面试·java-ee·八股
wen__xvn14 小时前
代码随想录算法训练营DAY10第五章 栈与队列part01
java·前端·算法
独自破碎E15 小时前
解释一下NIO、BIO、AIO
java·开发语言·nio
国强_dev15 小时前
在 Java 开发及其生态圈中“声东击西”的误导性错误
java·开发语言
FG.15 小时前
LangChain4j
java·spring boot·langchain4j
linweidong15 小时前
C++thread pool(线程池)设计应关注哪些扩展性问题?
java·数据库·c++
zfj32116 小时前
从源码层面解析一下ThreadLocal的工作原理
java·开发语言·threadlocal