MinIO中文官网http://www.minio.org.cn/MinIO安装创建Minio文件夹及bin、data、logs三个子文件夹官网下载MinIO Server和MinIO Client将下载好的两个.exe文件放在 Minio\bin 下创建startup.bat启动:: MINIO_ROOT_USER为客户端账号 :: MINIO_ROOT_PASSWORD为客户端密码 :: 如果不设置初始账号密码为minioadmin :: 注意账号必须3位密码必须大于8位 :: E:\Office\Minio\data为Minio存放地址请按实际修改 echo off set MINIO_ROOT_USERminioadmin set MINIO_ROOT_PASSWORDminioadmin minio.exe server E:\Office\Minio\data --console-address :9001 --address :9000 E:\Office\Minio\logs\minio.log 21访问客户端http://127.0.0.1:9000在SpringBoot使用中MinIO// Maven Central dependency groupIdio.minio/groupId artifactIdminio/artifactId version8.4.3/version /dependency// application.yml spring: minio: endpoint: http://127.0.0.1:9000 access-key: root secret-key: 61liuyao bucket-name: test-bucketpackage com.wyx.demoweb.config.minio; import io.minio.MinioClient; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class MinIOConfig { Value(${spring.minio.endpoint}) private String endpoint; Value(${spring.minio.access-key}) private String accessKey; Value(${spring.minio.secret-key}) private String secretKey; /** * 注入 MinioClient 客户端 */ Bean public MinioClient minioClient() { return MinioClient.builder() .endpoint(endpoint) .credentials(accessKey, secretKey) .build(); } }package com.wyx.demoweb.service.Utils; import com.alibaba.excel.util.StringUtils; import io.minio.*; import io.minio.http.Method; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import java.io.InputStream; import java.net.URLEncoder; import java.util.UUID; Component RequiredArgsConstructor public class MinIOUtil { private final MinioClient minioClient; Value(${spring.minio.endpoint}) private String endpoint; Value(${spring.minio.bucket-name}) private String bucketName; public String upload(MultipartFile file, String bucketName, String folderPath) throws Exception { bucketName toBucketName(bucketName); // 自动创建桶 boolean exists minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); if (!exists) { minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); } // 处理文件夹 if (folderPath ! null !folderPath.isEmpty() !folderPath.endsWith(/)) { folderPath /; } // 文件名 String originalFilename file.getOriginalFilename(); String suffix originalFilename.substring(originalFilename.lastIndexOf(.)); String objectName folderPath UUID.randomUUID() suffix; // 上传 minioClient.putObject( PutObjectArgs.builder() .bucket(bucketName) .object(objectName) .stream(file.getInputStream(), file.getSize(), -1) .contentType(file.getContentType()) .build() ); return endpoint / bucketName / objectName; } // 2. 解析 URL自动获取 bucket 和 objectName private String[] parseUrl(String fileUrl) { String afterEndpoint fileUrl.replace(endpoint /, ); String bucket afterEndpoint.split(/)[0]; String objectName afterEndpoint.replace(bucket /, ); return new String[]{bucket, objectName}; } // 3. 预览直接传 URL public String getPreviewUrl(String fileUrl) throws Exception { String[] arr parseUrl(fileUrl); String bucket arr[0]; String objectName arr[1]; return minioClient.getPresignedObjectUrl( GetPresignedObjectUrlArgs.builder() .method(Method.GET) .bucket(bucket) .object(objectName) .expiry(7, java.util.concurrent.TimeUnit.DAYS) .build() ); } // 4. 下载直接传 URL public void download(String fileUrl, HttpServletResponse response) throws Exception { String[] arr parseUrl(fileUrl); String bucket arr[0]; String objectName arr[1]; try (InputStream in minioClient.getObject( GetObjectArgs.builder().bucket(bucket).object(objectName).build() )) { String fileName objectName.substring(objectName.lastIndexOf(/) 1); response.setHeader(Content-Disposition, attachment;filename URLEncoder.encode(fileName, UTF-8)); response.setContentType(application/octet-stream); ServletOutputStream out response.getOutputStream(); byte[] buf new byte[2048]; int len; while ((len in.read(buf)) ! -1) { out.write(buf, 0, len); } out.flush(); out.close(); } } // 5. 删除直接传 URL public void delete(String fileUrl) throws Exception { String[] arr parseUrl(fileUrl); String bucket arr[0]; String objectName arr[1]; minioClient.removeObject( RemoveObjectArgs.builder().bucket(bucket).object(objectName).build() ); } private String toBucketName(String bucketName) { if(StringUtils.isEmpty(bucketName) || undefined.equals(bucketName)) { return this.bucketName; } return bucketName; } }package com.wyx.demoweb.controller.MinIO; import com.wyx.demoweb.controller.Interceptor.CrossAuth; import com.wyx.demoweb.service.Utils.MinIOUtil; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; RestController RequestMapping(/minio) RequiredArgsConstructor public class MinIOController { private final MinIOUtil minioUtil; CrossAuth PostMapping(/upload) public String upload( RequestParam(file) MultipartFile file, RequestParam(value bucketName, required false, defaultValue ) String bucketName, RequestParam(value folderPath,required false, defaultValue ) String folderPath ) throws Exception { return minioUtil.upload(file, bucketName, folderPath); } // 预览 CrossAuth GetMapping(/preview) public String preview(RequestParam(fileUrl) String fileUrl) throws Exception { return minioUtil.getPreviewUrl(fileUrl); } // 下载 CrossAuth GetMapping(/download) public void download(RequestParam(fileUrl) String fileUrl, HttpServletResponse response) throws Exception { minioUtil.download(fileUrl, response); } // 删除 CrossAuth DeleteMapping(/delete) public String delete(RequestParam(fileUrl) String fileUrl) throws Exception { minioUtil.delete(fileUrl); return 删除成功; } }