minio基本使用

直接docker润起来(其实是我用服务器运行一早上,没成功.......................)

bash 复制代码
docker run \
   -p 9000:9000 \
   -p 9001:9001 \
   --user $(id -u):$(id -g) \
   --name minio1 \
   -e "MINIO_ROOT_USER=ROOTUSER" \
   -e "MINIO_ROOT_PASSWORD=CHANGEME123" \
   -v ${HOME}/minio/data:/data \
   quay.io/minio/minio server /data --console-address ":9001"

9000是上传和下载的地址,就是提供给其他服务调用的地址。

9001是minio的管理页面的地址,在上面可以管理minio:

然后就是java调用:

配置:

XML 复制代码
server:
  port: 8001
minio:
  endpoint: http://192.168.126.134:9000 #Minio地址
  bucketName: backupstest #堆名
  accessKey: ROOTUSER #name
  secretKey: CHANGEME123 #密码

config文件:

java 复制代码
package com.example.miniodome.comfig;

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();
    }
}
java 复制代码
package com.example.miniodome.util;

import com.example.miniodome.comfig.MinioConfig;
import io.micrometer.common.util.StringUtils;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Component
@Slf4j
public class MinioUtil {
    @Autowired
    private MinioConfig prop;

    @Resource
    private MinioClient minioClient;

    /**
     * 查看存储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
     *
     * @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
     *
     * @return Boolean
     */
    public Boolean removeBucket(String bucketName) {
        try {
            minioClient.removeBucket(RemoveBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 获取全部bucket
     */
    public List<Bucket> getAllBuckets() {
        try {
            List<Bucket> buckets = minioClient.listBuckets();
            return buckets;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 文件上传
     *
     * @param file 文件
     * @return Boolean
     */
    public String upload(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        if (StringUtils.isBlank(originalFilename)) {
            throw new RuntimeException();
        }
        String fileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
        String objectName = LocalDate.now().toString() + fileName;
        try {
            PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(prop.getBucketName()).object(objectName)
                    .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
            //文件名称相同会覆盖
            minioClient.putObject(objectArgs);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return objectName;
    }

    public static void main(String[] args) {
        System.out.println(UUID.randomUUID());
    }

    /**
     * 预览图片
     *
     * @param fileName
     * @return
     */
    public String preview(String fileName) {
        // 查看文件地址
        GetPresignedObjectUrlArgs build = new GetPresignedObjectUrlArgs().builder().bucket(prop.getBucketName()).object(fileName).method(Method.GET).build();
        try {
            String url = minioClient.getPresignedObjectUrl(build);
            return url;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 文件下载
     *
     * @param fileName 文件名称
     * @param res      response
     * @return Boolean
     */
    public void download(String fileName, HttpServletResponse res) {
        GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(prop.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();
        }
    }

    /**
     * 查看文件对象
     *
     * @return 存储bucket内文件对象信息
     */
    public List<Item> listObjects() {
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder().bucket(prop.getBucketName()).build());
        List<Item> items = new ArrayList<>();
        try {
            for (Result<Item> result : results) {
                items.add(result.get());
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return items;
    }

    /**
     * 删除
     *
     * @param fileName
     * @return
     * @throws Exception
     */
    public boolean remove(String fileName) {
        try {
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(prop.getBucketName()).object(fileName).build());
        } catch (Exception e) {
            return false;
        }
        return true;
    }

}
java 复制代码
package com.example.miniodome.util;

import lombok.Data;

/**
 * @program: springCloudAlibaba
 * @author: quxiao
 * @create: 2024-03-07 17:21
 **/
@Data
public class MyResult<T> {
    private static final String SUCCESS_CODE = "200";
    private static final String SUCCESS_MSG = "操作成功";
    private static final String FALL_CODE = "500";
    private static final String FALL_MSG = "操作失败";
    private String msgName;
    private String msgCode;
    private Boolean status;
    private T data;

    public static MyResult success(Object data) {
        MyResult result = new MyResult();
        result.setData(data);
        result.setStatus(true);
        result.setMsgCode(SUCCESS_CODE);
        result.setMsgName(SUCCESS_MSG);
        return result;
    }

    public static MyResult success() {
        MyResult result = new MyResult();
        result.setStatus(true);
        result.setMsgCode(SUCCESS_CODE);
        result.setMsgName(SUCCESS_MSG);
        return result;
    }

    public static MyResult fail() {
        MyResult result = new MyResult();
        result.setStatus(false);
        result.setMsgCode(FALL_CODE);
        result.setMsgName(FALL_MSG);
        return result;
    }

    public static MyResult fail(Object data) {
        MyResult result = new MyResult();
        result.setStatus(false);
        result.setMsgCode(FALL_CODE);
        result.setMsgName(FALL_MSG);
        result.setData(data);
        return result;
    }
}
java 复制代码
package com.example.miniodome.controller;

import com.example.miniodome.comfig.MinioConfig;
import com.example.miniodome.util.MinioUtil;
import com.example.miniodome.util.MyResult;
import io.minio.messages.Bucket;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

//@Api(tags = "文件相关接口")
@Slf4j
@RestController
public class FileController {


    @Autowired
    private MinioUtil minioUtil;
    @Autowired
    private MinioConfig prop;

    // @ApiOperation(value = "查看存储bucket是否存在")
    @GetMapping("/bucketExists")
    public MyResult bucketExists(String bucketName) {
        return MyResult.success(minioUtil.bucketExists(bucketName));
    }

    // @ApiOperation(value = "创建存储bucket")
    @GetMapping("/makeBucket")
    public MyResult makeBucket(String bucketName) {
        minioUtil.makeBucket(bucketName);
        return MyResult.success();
    }

    // @ApiOperation(value = "删除存储bucket")
    @GetMapping("/removeBucket")
    public MyResult removeBucket(String bucketName) {
        minioUtil.removeBucket(bucketName);
        return MyResult.success();
    }

    // @ApiOperation(value = "获取全部bucket")
    @GetMapping("/getAllBuckets")
    public MyResult<List<Bucket>> getAllBuckets() {
        List<Bucket> allBuckets = minioUtil.getAllBuckets();
        return MyResult.success(allBuckets);
    }

    // @ApiOperation(value = "文件上传返回url")
    @PostMapping("/upload")
    public MyResult<String> upload(@RequestParam(value = "file") MultipartFile file) {
        String objectName = minioUtil.upload(file);
        if (null != objectName) {
            return MyResult.success(prop.getEndpoint() + "/" + prop.getBucketName() + "/" + objectName);
        }
        return MyResult.fail();
    }

    // @ApiOperation(value = "图片/视频预览")
    @GetMapping("/preview")
    public MyResult preview(@RequestParam("fileName") String fileName) {
        return MyResult.success(minioUtil.preview(fileName));
    }

    // @ApiOperation(value = "文件下载")
    @GetMapping("/download/{fileName}")
    public MyResult download(@PathVariable("fileName") String fileName, HttpServletResponse res) {
        minioUtil.download(fileName, res);
        return MyResult.success();
    }

    // @ApiOperation(value = "删除文件", notes = "根据url地址删除文件")
    @PostMapping("/delete")
    public MyResult remove(String url) {
        String objName = url.substring(url.lastIndexOf(prop.getBucketName() + "/") + prop.getBucketName().length() + 1);
        minioUtil.remove(objName);
        return MyResult.success();
    }

}

这里可以将提前生成的前缀存入数据库中,对应文件名。

然后调用下载的时候,就将文件名替换为真正的文件名,而不是用来标识准确文件的uuid前缀:

然后另一个就是,可以直接访问minio的资源,调用上传接口返回的url,但是需要在minio控制页面中配置:

相关推荐
LayZhangStrive6 分钟前
融360 一面
java·面试·后端开发
城管不管31 分钟前
重生——第十次面试之开源中国一面挂
java·linux·开发语言·算法·面试·职场和发展·开源
Java小白笔记35 分钟前
Windows系统免软件命令激活
java·网络·人工智能·windows·ai·ai编程
爱敲键盘的猴子44 分钟前
深入理解 Java HashMap
java·hashmap
霸道流氓气质44 分钟前
Java开发者AI编程常用MCP、Skills、Rules全景汇总
java·开发语言·ai编程
天涯醉青楼1 小时前
Spring Boot 接口返回 Bean 时字段名“变形”的深度剖析与解决方案
java
步行cgn1 小时前
MyBatis 高级映射与延迟加载完全指南
java·tomcat·mybatis
thefool1122661 小时前
从中序与后序遍历序列构造二叉树
java
吴声子夜歌1 小时前
Java面试题——JVM(二)
java·开发语言·jvm
CRMEB1 小时前
商城大促活动策划全流程:从定目标到复盘四阶段
java·开发语言·人工智能·ai·开源·php