docker部署
docker run \-p 9000:9000 \-p 9001:9001 \-d \--name minio \-v /Users/ivan/code/black/dockerData/minio:/data \-e "MINIO_ROOT_USER=ROOT" \-e "MINIO_ROOT_PASSWORD=MINIO123" \quay.io/minio/minio server /data --console-address ":9001"
管理后台 localhost:9001 用户名ROOT 密码MINIO123
上传以后的文件,通过localhost:9000/xxx来访问
sprinboo3集成
依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId></dependency>
</dependencies>
Springboot3封装starter
@Data
@Configuration
@EnableConfigurationProperties({MinIOConfigProperties.class})
//当引入FileStorageService接口时
@ConditionalOnClass(FileStorageService.class)
public class MinIOConfig {@Autowiredprivate MinIOConfigProperties minIOConfigProperties;@Beanpublic MinioClient buildMinioClient(){return MinioClient.builder().credentials(minIOConfigProperties.getAccessKey(), minIOConfigProperties.getSecretKey()).endpoint(minIOConfigProperties.getEndpoint()).build();}
}
package com.shenzhen.dai.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;import java.io.Serializable;@Data
@Configuration
@ConfigurationProperties(prefix = "minio") // 文件上传 配置前缀file.oss
public class MinIOConfigProperties implements Serializable {private String accessKey;private String secretKey;private String bucket;private String endpoint;private String readPath;
}
package com.shenzhen.dai.service;import java.io.InputStream;/*** @author itheima*/
public interface FileStorageService {/*** 上传自定义格式文件** @param filePath 文件路径* @param contentType 文件类型* @param filename 文件名* @param inputStream 文件流* @return 文件全路径*/String uploadFile(String filePath, String filename, String contentType, InputStream inputStream);/*** 上传图片文件** @param prefix 文件前缀* @param filename 文件名* @param inputStream 文件流* @return 文件全路径*/String uploadImgFile(String prefix, String filename, InputStream inputStream);/*** 上传html文件** @param prefix 文件前缀* @param filename 文件名* @param inputStream 文件流* @return 文件全路径*/String uploadHtmlFile(String prefix, String filename, InputStream inputStream);/*** 删除文件** @param pathUrl 文件全路径*/void delete(String pathUrl);/*** 下载文件** @param pathUrl 文件全路径* @return*/byte[] downLoadFile(String pathUrl);}
package com.shenzhen.dai.service.impl;import com.shenzhen.dai.config.MinIOConfig;
import com.shenzhen.dai.config.MinIOConfigProperties;
import com.shenzhen.dai.service.FileStorageService;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;@Slf4j
@EnableConfigurationProperties(MinIOConfigProperties.class)
@Import(MinIOConfig.class)
@Service
public class MinIOFileStorageService implements FileStorageService {@Autowiredprivate MinioClient minioClient;@Autowiredprivate MinIOConfigProperties minIOConfigProperties;private final static String separator = "/";/*** @param dirPath* @param filename yyyy/mm/dd/file.jpg* @return*/public String builderFilePath(String dirPath, String filename) {StringBuilder stringBuilder = new StringBuilder(50);if (!StringUtils.isEmpty(dirPath)) {stringBuilder.append(dirPath).append(separator);}SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");String todayStr = sdf.format(new Date());stringBuilder.append(todayStr).append(separator);stringBuilder.append(filename);return stringBuilder.toString();}@Overridepublic String uploadFile(String filePath, String filename, String contentType, InputStream inputStream) {try {PutObjectArgs putObjectArgs = PutObjectArgs.builder().object(filePath).contentType(contentType).bucket(minIOConfigProperties.getBucket()).stream(inputStream, inputStream.available(), -1).build();minioClient.putObject(putObjectArgs);StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath());urlPath.append(separator).append(minIOConfigProperties.getReadPath());urlPath.append(separator).append(filePath);return urlPath.toString();} catch (Exception ex) {log.error("minio put file error.", ex);throw new RuntimeException(filename + "上传失败");}}/*** 上传图片文件** @param prefix 文件前缀* @param filename 文件名* @param inputStream 文件流* @return 文件全路径*/@Overridepublic String uploadImgFile(String prefix, String filename, InputStream inputStream) {String filePath = builderFilePath(prefix, filename);try {PutObjectArgs putObjectArgs = PutObjectArgs.builder().object(filePath).contentType("image/jpg").bucket(minIOConfigProperties.getBucket()).stream(inputStream, inputStream.available(), -1).build();minioClient.putObject(putObjectArgs);StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath());urlPath.append(separator + minIOConfigProperties.getBucket());urlPath.append(separator);urlPath.append(filePath);return urlPath.toString();} catch (Exception ex) {log.error("minio put file error.", ex);throw new RuntimeException("上传文件失败");}}/*** 上传html文件** @param prefix 文件前缀* @param filename 文件名* @param inputStream 文件流* @return 文件全路径*/@Overridepublic String uploadHtmlFile(String prefix, String filename, InputStream inputStream) {String filePath = builderFilePath(prefix, filename);try {PutObjectArgs putObjectArgs = PutObjectArgs.builder().object(filePath).contentType("text/html").bucket(minIOConfigProperties.getBucket()).stream(inputStream, inputStream.available(), -1).build();minioClient.putObject(putObjectArgs);StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath());urlPath.append(separator + minIOConfigProperties.getBucket());urlPath.append(separator);urlPath.append(filePath);return urlPath.toString();} catch (Exception ex) {log.error("minio put file error.", ex);ex.printStackTrace();throw new RuntimeException("上传文件失败");}}/*** 删除文件** @param pathUrl 文件全路径*/@Overridepublic void delete(String pathUrl) {String key = pathUrl.replace(minIOConfigProperties.getEndpoint() + "/", "");int index = key.indexOf(separator);String bucket = key.substring(0, index);String filePath = key.substring(index + 1);// 删除ObjectsRemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucket).object(filePath).build();try {minioClient.removeObject(removeObjectArgs);} catch (Exception e) {log.error("minio remove file error. pathUrl:{}", pathUrl);e.printStackTrace();}}/*** 下载文件** @param pathUrl 文件全路径* @return 文件流*/@Overridepublic byte[] downLoadFile(String pathUrl) {String key = pathUrl.replace(minIOConfigProperties.getEndpoint() + "/", "");int index = key.indexOf(separator);String bucket = key.substring(0, index);String filePath = key.substring(index + 1);InputStream inputStream = null;try {inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(minIOConfigProperties.getBucket()).object(filePath).build());} catch (Exception e) {log.error("minio down file error. pathUrl:{}", pathUrl);e.printStackTrace();}ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();byte[] buff = new byte[100];int rc = 0;while (true) {try {if (!((rc = inputStream.read(buff, 0, 100)) > 0)) break;} catch (IOException e) {e.printStackTrace();}byteArrayOutputStream.write(buff, 0, rc);}return byteArrayOutputStream.toByteArray();}
}
resources下创建META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.shenzhen.dai.service.impl.MinIOFileStorageService
其他项目使用
引入依赖
<dependency><groupId>com.shenzhen.dai</groupId><artifactId>black-news-starter-file</artifactId><version>1.0-SNAPSHOT</version>
</dependency>
增加配置
minio:accessKey: Kjcacew7Jq5x5vk0UfEYsecretKey: UHrHzJADSIqZcj4eATNFMIkl2yA9grXsuXm3j8DAbucket: blackendpoint: http://localhost:9000readPath: http://localhost:9000