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);
    }
}
相关推荐
惊讶的猫15 小时前
探究StringBuilder和StringBuffer的线程安全问题
java·开发语言
jmxwzy15 小时前
Spring全家桶
java·spring·rpc
Halo_tjn15 小时前
基于封装的专项 知识点
java·前端·python·算法
Fleshy数模16 小时前
从数据获取到突破限制:Python爬虫进阶实战全攻略
java·开发语言
像少年啦飞驰点、16 小时前
零基础入门 Spring Boot:从“Hello World”到可上线的 Web 应用全闭环指南
java·spring boot·web开发·编程入门·后端开发
苍煜16 小时前
万字详解Maven打包策略:从基础插件到多模块实战
java·maven
有来技术16 小时前
Spring Boot 4 + Vue3 企业级多租户 SaaS:从共享 Schema 架构到商业化套餐设计
java·vue.js·spring boot·后端
东东51616 小时前
xxx医患档案管理系统
java·spring boot·vue·毕业设计·智慧城市
一个响当当的名号17 小时前
lectrue9 索引并发控制
java·开发语言·数据库
进阶小白猿17 小时前
Java技术八股学习Day30
java·开发语言·学习