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 {
@Autowired
private MinIOConfigProperties minIOConfigProperties;
@Bean
public 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 {
@Autowired
private MinioClient minioClient;
@Autowired
private 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();
}
@Override
public 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 檔案全路徑
*/
@Override
public 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 檔案全路徑
*/
@Override
public 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 檔案全路徑
*/
@Override
public 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);
// 刪除Objects
RemoveObjectArgs 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 檔案流
*/
@Override
public 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: Kjcacew7Jq5x5vk0UfEY
secretKey: UHrHzJADSIqZcj4eATNFMIkl2yA9grXsuXm3j8DA
bucket: black
endpoint: http://localhost:9000
readPath: http://localhost:9000