引入依赖
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.2</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.17.1</version>
</dependency>
配置
oss:
type: MINIO
endpoint: http://192.168.249.132:9001
accessKey: xxx
secretKey: xxx
bucket: test
prefix:
nginxHost:
配置属性类
package com.qiangesoft.oss.config;
import com.qiangesoft.oss.constant.FileStoreTypeEnum;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "oss")
public class FileStoreProperties {
private FileStoreTypeEnum type = FileStoreTypeEnum.LOCAL;
private String endpoint;
private String accessKey;
private String secretKey;
private String bucket;
private String prefix;
private String nginxHost;
}
策略工厂
package com.qiangesoft.oss.config;
import com.qiangesoft.oss.constant.FileStoreTypeEnum;
import com.qiangesoft.oss.strategy.FileStrategy;
import org.springframework.util.ObjectUtils;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public final class StrategyFactory {
private static final Map<FileStoreTypeEnum, FileStrategy> STRATEGY_MAP = new ConcurrentHashMap<>();
public static FileStrategy getStrategy(FileStoreTypeEnum type) {
return STRATEGY_MAP.get(type);
}
public static void register(FileStoreTypeEnum type, FileStrategy strategy) {
if (ObjectUtils.isEmpty(type)) {
return;
}
STRATEGY_MAP.put(type, strategy);
}
}
策略接口
package com.qiangesoft.oss.strategy;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
public interface FileStrategy extends InitializingBean {
String POINT = ".";
String SLASH = "/";
boolean existsCatalog(String catalog) throws Exception;
void createCatalog(String catalog) throws Exception;
List<String> listCatalogs() throws Exception;
void removeCatalog(String catalog) throws Exception;
String uploadFile(String catalog, MultipartFile file) throws Exception;
void removeFile(String catalog, String fileName) throws Exception;
void removeFiles(String catalog, List<String> fileNames) throws Exception;
}
策略实现类
package com.qiangesoft.oss.strategy;
import com.qiangesoft.oss.config.FileStoreProperties;
import com.qiangesoft.oss.config.StrategyFactory;
import com.qiangesoft.oss.constant.FileStoreTypeEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@RequiredArgsConstructor
@Service
@Primary
@ConditionalOnProperty(prefix = "oss", name = "type", havingValue = "local")
public class LocalStrategyImpl implements FileStrategy {
private String prefix;
public LocalStrategyImpl(FileStoreProperties fileStoreProperties) {
this.prefix = fileStoreProperties.getPrefix();
}
@Override
public boolean existsCatalog(String catalog) throws Exception {
File file = new File(prefix + SLASH + catalog);
return file.exists();
}
@Override
public void createCatalog(String catalog) throws Exception {
File file = new File(prefix + SLASH + catalog);
if (!file.exists()) {
file.mkdirs();
}
}
@Override
public List<String> listCatalogs() throws Exception {
File file = new File(prefix);
File[] files = file.listFiles();
List<String> list = new ArrayList<>();
for (File subFile : files) {
if (subFile.isDirectory()) {
list.add(subFile.getName());
}
}
return list;
}
@Override
public void removeCatalog(String catalog) throws Exception {
File file = new File(prefix + SLASH + catalog);
if (file.exists()) {
file.delete();
}
}
@Override
public String uploadFile(String catalog, MultipartFile file) throws Exception {
return null;
}
@Override
public void removeFile(String catalog, String fileName) throws Exception {
}
@Override
public void removeFiles(String catalog, List<String> fileNames) throws Exception {
}
@Override
public void afterPropertiesSet() throws Exception {
StrategyFactory.register(FileStoreTypeEnum.LOCAL, this);
}
}
package com.qiangesoft.oss.strategy;
import com.qiangesoft.oss.config.FileStoreProperties;
import com.qiangesoft.oss.config.StrategyFactory;
import com.qiangesoft.oss.constant.FileStoreTypeEnum;
import io.minio.*;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@RequiredArgsConstructor
@Service
@ConditionalOnProperty(prefix = "oss", name = "type", havingValue = "minio")
public class MinioStrategyImpl implements FileStrategy {
private MinioClient minioClient;
public MinioStrategyImpl(FileStoreProperties fileStoreProperties) {
this.minioClient = MinioClient.builder()
.credentials(fileStoreProperties.getAccessKey(), fileStoreProperties.getSecretKey())
.endpoint(fileStoreProperties.getEndpoint())
.build();
}
@Override
public boolean existsCatalog(String catalog) throws Exception {
BucketExistsArgs args = BucketExistsArgs.builder().bucket(catalog).build();
return minioClient.bucketExists(args);
}
@Override
public void createCatalog(String catalog) throws Exception {
if (!this.existsCatalog(catalog)) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(catalog).build());
}
}
@Override
public List<String> listCatalogs() throws Exception {
return minioClient.listBuckets().stream().map(Bucket::name).collect(Collectors.toList());
}
@Override
public void removeCatalog(String catalog) throws Exception {
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(catalog).build());
}
@Override
public String uploadFile(String catalog, MultipartFile file) throws Exception {
Assert.notNull(catalog, "bucketName is not blank");
Assert.notNull(file, "file is not null");
createCatalog(catalog);
String filename = file.getOriginalFilename();
minioClient.putObject(PutObjectArgs.builder()
.bucket(catalog)
.object(filename)
.stream(file.getInputStream(), file.getSize(), -1)
.contentType(file.getContentType())
.build());
return catalog + SLASH + filename;
}
@Override
public void removeFile(String catalog, String fileName) throws Exception {
minioClient.removeObject(RemoveObjectArgs.builder().bucket(catalog).object(fileName).build());
}
@Override
public void removeFiles(String catalog, List<String> fileNames) throws Exception {
List<DeleteObject> deleteObjectList = new ArrayList<>();
for (String fileName : fileNames) {
DeleteObject deleteObject = new DeleteObject(fileName);
deleteObjectList.add(deleteObject);
}
Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(catalog).objects(deleteObjectList).build());
for (Result<DeleteError> result : results) {
DeleteError error = result.get();
log.error("Error in deleting object " + error.objectName() + "; " + error.message());
}
}
@Override
public void afterPropertiesSet() throws Exception {
StrategyFactory.register(FileStoreTypeEnum.MINIO, this);
}
}
package com.qiangesoft.oss.strategy;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.aliyun.oss.model.DeleteObjectsResult;
import com.qiangesoft.oss.config.FileStoreProperties;
import com.qiangesoft.oss.config.StrategyFactory;
import com.qiangesoft.oss.constant.FileStoreTypeEnum;
import io.minio.messages.DeleteObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@RequiredArgsConstructor
@Service
@ConditionalOnProperty(prefix = "oss", name = "type", havingValue = "aliyun")
public class AliyunStrategyImpl implements FileStrategy {
private OSS ossClient;
public AliyunStrategyImpl(FileStoreProperties fileStoreProperties) {
this.ossClient = new OSSClientBuilder().build(fileStoreProperties.getEndpoint(),
fileStoreProperties.getAccessKey(), fileStoreProperties.getSecretKey());
}
@Override
public boolean existsCatalog(String catalog) throws Exception {
return ossClient.doesBucketExist(catalog);
}
@Override
public void createCatalog(String catalog) throws Exception {
if (!this.existsCatalog(catalog)) {
ossClient.createBucket(catalog);
}
}
@Override
public List<String> listCatalogs() throws Exception {
return ossClient.listBuckets().stream().map(Bucket::getName).collect(Collectors.toList());
}
@Override
public void removeCatalog(String catalog) throws Exception {
ossClient.deleteBucket(catalog);
}
@Override
public String uploadFile(String catalog, MultipartFile file) throws Exception {
Assert.notNull(catalog, "bucketName is not blank");
Assert.notNull(file, "file is not null");
createCatalog(catalog);
String filename = file.getOriginalFilename();
ossClient.putObject(catalog, filename, file.getInputStream());
return catalog + SLASH + filename;
}
@Override
public void removeFile(String catalog, String fileName) throws Exception {
ossClient.deleteObject(catalog, fileName);
}
@Override
public void removeFiles(String catalog, List<String> fileNames) throws Exception {
List<DeleteObject> deleteObjectList = new ArrayList<>();
for (String fileName : fileNames) {
DeleteObject deleteObject = new DeleteObject(fileName);
deleteObjectList.add(deleteObject);
}
DeleteObjectsResult result = ossClient.deleteObjects(new DeleteObjectsRequest(catalog).withKeys(fileNames));
}
@Override
public void afterPropertiesSet() throws Exception {
StrategyFactory.register(FileStoreTypeEnum.ALI_OSS, this);
}
}
文件服务类
package com.qiangesoft.oss.service;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
public interface IFileService {
void createCatalog(String catalog) throws Exception;
List<String> listCatalogs() throws Exception;
void removeCatalog(String catalog) throws Exception;
String uploadFile(String catalog, MultipartFile file) throws Exception;
void removeFile(String catalog, String fileName) throws Exception;
void removeFiles(String catalog, List<String> fileNames) throws Exception;
}
package com.qiangesoft.oss.service;
import com.qiangesoft.oss.config.FileStoreProperties;
import com.qiangesoft.oss.config.StrategyFactory;
import com.qiangesoft.oss.strategy.FileStrategy;
import org.springframework.beans.BeansException;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
@Service
public class FileServiceImpl implements IFileService, ApplicationContextAware, CommandLineRunner {
private ApplicationContext applicationContext;
private FileStrategy fileStrategy;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void run(String... args) throws Exception {
FileStoreProperties fileStoreProperties = this.applicationContext.getBean(FileStoreProperties.class);
fileStrategy = StrategyFactory.getStrategy(fileStoreProperties.getType());
}
@Override
public void createCatalog(String catalog) throws Exception {
fileStrategy.createCatalog(catalog);
}
@Override
public List<String> listCatalogs() throws Exception {
return fileStrategy.listCatalogs();
}
@Override
public void removeCatalog(String catalog) throws Exception {
fileStrategy.removeCatalog(catalog);
}
@Override
public String uploadFile(String catalog, MultipartFile file) throws Exception {
return fileStrategy.uploadFile(catalog, file);
}
@Override
public void removeFile(String catalog, String fileName) throws Exception {
fileStrategy.removeFile(catalog, fileName);
}
@Override
public void removeFiles(String catalog, List<String> fileNames) throws Exception {
fileStrategy.removeFiles(catalog, fileNames);
}
}