maven依赖:
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.5.14</version><exclusions><exclusion><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId></exclusion></exclusions></dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.11.0</version> </dependency>
yaml配置:
# MinIO 配置
minio:endpoint: http://xxx.xx.xx.xx:9000accesskey: adminsecretKey: xxxxbucketName: workconnectTimeout: 60000writeTimeout: 60000readTimeout: 60000
package com.r.minio.config;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("${minio.endpoint}")private String endpoint;@Value("${minio.accesskey}")private String accessKey;@Value("${minio.secretKey}")private String secretKey;@Beanpublic MinioClient minioClient() {return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();}
}
package com.r.minio.properties;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioProperties {private String endpoint;private String accessKey;private String secretKey;private String bucketName;private Integer connectTimeout;private Integer writeTimeout;private Integer readTimeout;public String getEndpoint() {return endpoint;}public void setEndpoint(String endpoint) {this.endpoint = endpoint;}public String getAccessKey() {return accessKey;}public void setAccessKey(String accessKey) {this.accessKey = accessKey;}public String getSecretKey() {return secretKey;}public void setSecretKey(String secretKey) {this.secretKey = secretKey;}public String getBucketName() {return bucketName;}public void setBucketName(String bucketName) {this.bucketName = bucketName;}public Integer getConnectTimeout() {return connectTimeout;}public void setConnectTimeout(Integer connectTimeout) {this.connectTimeout = connectTimeout;}public Integer getWriteTimeout() {return writeTimeout;}public void setWriteTimeout(Integer writeTimeout) {this.writeTimeout = writeTimeout;}public Integer getReadTimeout() {return readTimeout;}public void setReadTimeout(Integer readTimeout) {this.readTimeout = readTimeout;}
}
package com.r.minio.service;import org.springframework.web.multipart.MultipartFile;import java.io.InputStream;
import java.util.Map;
public interface MinioService {String uploadFile(MultipartFile file);String uploadFile(MultipartFile file, String bucketName);String uploadFile(MultipartFile file, String path, String bucketName);String uploadFile(MultipartFile file, Map<String, String> metadata);String uploadFile(InputStream stream, String fileName, String contentType);String getObjectUrl(String objectName);String getObjectUrl(String objectName, Integer expires);boolean removeFile(String objectName);boolean removeFile(String bucketName, String objectName);boolean bucketExists(String bucketName);void makeBucket(String bucketName);
}
package com.r.minio.service.impl;import com.r.minio.service.MinioService;
import com.r.minio.properties.MinioProperties;
import io.minio.*;
import io.minio.http.Method;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import java.io.InputStream;
import java.util.Map;
import java.util.UUID;
@Slf4j
@Service
public class MinioServiceImpl implements MinioService {@Autowiredprivate MinioClient minioClient;@Autowiredprivate MinioProperties minioProperties;@Overridepublic String uploadFile(MultipartFile file) {return uploadFile(file, minioProperties.getBucketName());}@Overridepublic String uploadFile(MultipartFile file,String path ,String bucketName) {try{if (!bucketExists(bucketName)){makeBucket(bucketName);}String originalFilename = file.getOriginalFilename();assert originalFilename != null;String fileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));PutObjectArgs args = PutObjectArgs.builder().bucket(bucketName).object(path+fileName).stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();minioClient.putObject(args);log.info("文件上传成功: {}", fileName);return fileName;} catch (Exception e){log.error("文件上传失败: {}", e.getMessage(), e);throw new RuntimeException("文件上传失败", e);}}@Overridepublic String uploadFile(MultipartFile file, String bucketName) {try{if (!bucketExists(bucketName)){makeBucket(bucketName);}String originalFilename = file.getOriginalFilename();assert originalFilename != null;String fileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));PutObjectArgs args = PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();minioClient.putObject(args);log.info("文件上传成功: {}", fileName);return fileName;} catch (Exception e){log.error("文件上传失败: {}", e.getMessage(), e);throw new RuntimeException("文件上传失败", e);}}@Overridepublic String uploadFile(MultipartFile file, Map<String, String> metadata) {try{String bucketName = minioProperties.getBucketName();if (!bucketExists(bucketName)){makeBucket(bucketName);}String originalFilename = file.getOriginalFilename();assert originalFilename != null;String fileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));PutObjectArgs args = PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).userMetadata(metadata).build();minioClient.putObject(args);log.info("文件上传成功: {}", fileName);return fileName;} catch (Exception e){log.error("文件上传失败: {}", e.getMessage(), e);throw new RuntimeException("文件上传失败", e);}}@Overridepublic String uploadFile(InputStream stream, String fileName, String contentType) {try{String bucketName = minioProperties.getBucketName();if (!bucketExists(bucketName)){makeBucket(bucketName);}PutObjectArgs args = PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(stream, -1, 10485760).contentType(contentType).build();minioClient.putObject(args);log.info("文件上传成功: {}", fileName);return fileName;} catch (Exception e){log.error("文件上传失败: {}", e.getMessage(), e);throw new RuntimeException("文件上传失败", e);}}@Overridepublic String getObjectUrl(String objectName) {return getObjectUrl(objectName, 7 * 24 * 60 * 60);}@Overridepublic String getObjectUrl(String objectName, Integer expires) {try{GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(minioProperties.getBucketName()).object(objectName).expiry(expires).build();return minioClient.getPresignedObjectUrl(args);} catch (Exception e){log.error("获取文件URL失败: {}", e.getMessage(), e);throw new RuntimeException("获取文件URL失败", e);}}@Overridepublic boolean removeFile(String objectName) {return removeFile(minioProperties.getBucketName(), objectName);}@Overridepublic boolean removeFile(String bucketName, String objectName) {try{RemoveObjectArgs args = RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build();minioClient.removeObject(args);log.info("文件删除成功: {}", objectName);return true;} catch (Exception e){log.error("文件删除失败: {}", e.getMessage(), e);return false;}}@Overridepublic boolean bucketExists(String bucketName) {try{BucketExistsArgs args = BucketExistsArgs.builder().bucket(bucketName).build();return minioClient.bucketExists(args);} catch (Exception e){log.error("检查存储桶是否存在失败: {}", e.getMessage(), e);return false;}}@Overridepublic void makeBucket(String bucketName) {try{MakeBucketArgs args = MakeBucketArgs.builder().bucket(bucketName).build();minioClient.makeBucket(args);log.info("创建存储桶成功: {}", bucketName);} catch (Exception e){log.error("创建存储桶失败: {}", e.getMessage(), e);throw new RuntimeException("创建存储桶失败", e);}}
}