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 小时前
Spring Boot:如何测试Java Controller中的POST请求?
java·开发语言
爬山算法14 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
kfyty72515 小时前
集成 spring-ai 2.x 实践中遇到的一些问题及解决方案
java·人工智能·spring-ai
猫头虎15 小时前
如何排查并解决项目启动时报错Error encountered while processing: java.io.IOException: closed 的问题
java·开发语言·jvm·spring boot·python·开源·maven
李少兄15 小时前
在 IntelliJ IDEA 中修改 Git 远程仓库地址
java·git·intellij-idea
忆~遂愿15 小时前
ops-cv 算子库深度解析:面向视觉任务的硬件优化与数据布局(NCHW/NHWC)策略
java·大数据·linux·人工智能
小韩学长yyds15 小时前
Java序列化避坑指南:明确这4种场景,再也不盲目实现Serializable
java·序列化
仟濹15 小时前
【Java基础】多态 | 打卡day2
java·开发语言
Re.不晚15 小时前
JAVA进阶之路——无奖问答挑战2
java·开发语言
Ro Jace16 小时前
计算机专业基础教材
java·开发语言