彻底铲除OSSUtil,抽象、修改

This commit is contained in:
2024-12-26 19:34:20 +08:00
parent 473e7080a1
commit 201a6617ac
45 changed files with 765 additions and 317 deletions

View File

@@ -0,0 +1,53 @@
package com.ycwl.basic.storage;
import com.ycwl.basic.storage.adapters.AliOssAdapter;
import com.ycwl.basic.storage.adapters.IStorageAdapter;
import com.ycwl.basic.storage.adapters.LocalStorageAdapter;
import com.ycwl.basic.storage.entity.StorageConfig;
import com.ycwl.basic.storage.enums.StorageType;
import com.ycwl.basic.storage.exceptions.StorageUndefinedException;
import com.ycwl.basic.storage.exceptions.StorageUnsupportedException;
import java.util.HashMap;
import java.util.Map;
public class StorageFactory {
public static IStorageAdapter get(StorageType storageType, StorageConfig config) {
IStorageAdapter adapter = get(storageType);
adapter.setConfig(config);
return adapter;
}
public static IStorageAdapter get(StorageType storageType) {
switch (storageType) {
case LOCAL:
return new LocalStorageAdapter();
case ALI_OSS:
return new AliOssAdapter();
default:
throw new StorageUnsupportedException(storageType.getType());
}
}
public static IStorageAdapter get(String type) {
StorageType storageType = StorageType.getStorageType(type);
if (storageType == null) {
throw new StorageUnsupportedException(type);
}
return get(storageType);
}
public static Map<String, IStorageAdapter> definedName = new HashMap<>();
public static void register(String name, IStorageAdapter adapter) {
definedName.put(name, adapter);
}
public static IStorageAdapter use(String name) {
IStorageAdapter adapter = definedName.get(name);
if (adapter == null) {
throw new StorageUndefinedException(name);
}
return adapter;
}
}

View File

@@ -0,0 +1,46 @@
package com.ycwl.basic.storage.adapters;
import com.ycwl.basic.storage.entity.StorageConfig;
import com.ycwl.basic.storage.exceptions.UploadFileFailedException;
import lombok.Setter;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Date;
public abstract class AStorageAdapter implements IStorageAdapter {
@Override
public String uploadFile(File file, String path, String filename) {
if (file == null) {
return null;
}
try {
InputStream inputStream = new FileInputStream(file);
return uploadFile(inputStream, path, filename);
} catch (FileNotFoundException e) {
throw new UploadFileFailedException("文件不存在");
}
}
@Override
public String uploadFile(MultipartFile file, String path, String filename) {
if (file == null) {
return null;
}
try {
InputStream inputStream = file.getInputStream();
return uploadFile(inputStream, path, filename);
} catch (Exception e) {
throw new UploadFileFailedException("文件上传失败");
}
}
@Override
public String getUrlForUpload(String path, String filename) {
return getUrlForUpload(path, filename, new Date(System.currentTimeMillis() + 1000 * 60 * 60));
}
}

View File

@@ -0,0 +1,102 @@
package com.ycwl.basic.storage.adapters;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.ycwl.basic.storage.entity.AliOssStorageConfig;
import com.ycwl.basic.storage.entity.StorageConfig;
import com.ycwl.basic.storage.exceptions.StorageConfigException;
import com.ycwl.basic.storage.exceptions.UploadFileFailedException;
import com.ycwl.basic.storage.utils.StorageUtil;
import org.apache.commons.lang3.StringUtils;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.Map;
public class AliOssAdapter extends AStorageAdapter {
private AliOssStorageConfig config;
@Override
public void loadConfig(Map<String, String> _config) {
AliOssStorageConfig config = new AliOssStorageConfig();
config.setAccessKeyId(_config.get("accessKeyId"));
config.setAccessKeySecret(_config.get("accessKeySecret"));
config.setBucketName(_config.get("bucketName"));
config.setEndpoint(_config.get("endpoint"));
config.setRegion(_config.get("region"));
config.setUrl(_config.get("url"));
config.setPrefix(_config.get("prefix"));
config.checkEverythingOK();
this.config = config;
}
@Override
public void setConfig(StorageConfig config) {
if (config == null) {
throw new StorageConfigException("配置为空");
}
if (config instanceof AliOssStorageConfig) {
this.config = (AliOssStorageConfig) config;
} else {
throw new StorageConfigException("配置类型错误,传入的类为:" + config.getClass().getName());
}
}
@Override
public String uploadFile(InputStream inputStream, String path, String filename) {
if (inputStream == null) {
return null;
}
String fullPath = buildPath(path, filename);
OSS ossClient = getOssClient();
try {
PutObjectRequest putObjectRequest = new PutObjectRequest(config.getBucketName(), fullPath, inputStream);
ossClient.putObject(putObjectRequest);
return getUrl(path, filename);
} catch (ClientException e) {
throw new UploadFileFailedException("上传文件失败:" + e.getErrorMessage());
}
}
@Override
public boolean deleteFile(String path, String filename) {
OSS ossClient = getOssClient();
try {
ossClient.deleteObject(config.getBucketName(), buildPath(path, filename));
return true;
} catch (ClientException e) {
return false;
}
}
@Override
public String getUrl(String path, String filename) {
return config.getUrl() + buildPath(path, filename);
}
@Override
public String getUrlForUpload(String path, String filename, Date expireDate) {
OSS ossClient = getOssClient();
URL url = ossClient.generatePresignedUrl(config.getBucketName(), buildPath(path, filename), expireDate, HttpMethod.PUT);
return url.toString();
}
private OSS getOssClient() {
OSS ossClient = new OSSClientBuilder().build(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret());
return ossClient;
}
private String buildPath(String ...paths) {
if (StringUtils.isNotBlank(config.getPrefix())) {
return StorageUtil.joinPath(config.getPrefix(), paths);
} else {
return StorageUtil.joinPath(paths);
}
}
}

View File

@@ -0,0 +1,21 @@
package com.ycwl.basic.storage.adapters;
import com.ycwl.basic.storage.entity.StorageConfig;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.InputStream;
import java.util.Date;
import java.util.Map;
public interface IStorageAdapter {
void loadConfig(Map<String, String> config);
void setConfig(StorageConfig config);
String uploadFile(InputStream inputStream, String path, String filename);
String uploadFile(File file, String path, String filename);
String uploadFile(MultipartFile file, String path, String filename);
boolean deleteFile(String path, String filename);
String getUrl(String path, String filename);
String getUrlForUpload(String path, String filename);
String getUrlForUpload(String path, String filename, Date expireDate);
}

View File

@@ -0,0 +1,39 @@
package com.ycwl.basic.storage.adapters;
import com.ycwl.basic.storage.entity.StorageConfig;
import java.io.InputStream;
import java.util.Date;
import java.util.Map;
public class LocalStorageAdapter extends AStorageAdapter{
@Override
public void loadConfig(Map<String, String> config) {
}
@Override
public void setConfig(StorageConfig config) {
}
@Override
public String uploadFile(InputStream inputStream, String path, String filename) {
return "";
}
@Override
public boolean deleteFile(String path, String filename) {
return false;
}
@Override
public String getUrl(String path, String filename) {
return "";
}
@Override
public String getUrlForUpload(String path, String filename, Date expireDate) {
return "";
}
}

View File

@@ -0,0 +1,21 @@
package com.ycwl.basic.storage.entity;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class AliOssStorageConfig extends StorageConfig {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
private String url;
private String region;
private String prefix;
@Override
public void checkEverythingOK() {
// TODO: 检查配置是否正确
}
}

View File

@@ -0,0 +1,5 @@
package com.ycwl.basic.storage.entity;
public abstract class StorageConfig {
public abstract void checkEverythingOK();
}

View File

@@ -0,0 +1,27 @@
package com.ycwl.basic.storage.enums;
import com.ycwl.basic.storage.adapters.AliOssAdapter;
import com.ycwl.basic.storage.adapters.IStorageAdapter;
import com.ycwl.basic.storage.adapters.LocalStorageAdapter;
import lombok.Getter;
public enum StorageType {
LOCAL("LOCAL"),
ALI_OSS("ALI_OSS");
@Getter
private final String type;
StorageType(String type) {
this.type = type;
}
public static StorageType getStorageType(String type) {
for (StorageType storageType : StorageType.values()) {
if (storageType.getType().equals(type)) {
return storageType;
}
}
return null;
}
}

View File

@@ -0,0 +1,7 @@
package com.ycwl.basic.storage.exceptions;
public class StorageConfigException extends StorageException {
public StorageConfigException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,7 @@
package com.ycwl.basic.storage.exceptions;
public class StorageException extends RuntimeException {
public StorageException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,7 @@
package com.ycwl.basic.storage.exceptions;
public class StorageUndefinedException extends StorageException {
public StorageUndefinedException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,7 @@
package com.ycwl.basic.storage.exceptions;
public class StorageUnsupportedException extends StorageException {
public StorageUnsupportedException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,7 @@
package com.ycwl.basic.storage.exceptions;
public class UploadFileFailedException extends StorageException {
public UploadFileFailedException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,30 @@
package com.ycwl.basic.storage.starter;
import com.ycwl.basic.storage.StorageFactory;
import com.ycwl.basic.storage.adapters.IStorageAdapter;
import com.ycwl.basic.storage.starter.config.OverallStorageConfig;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
@Configuration
public class StorageAutoConfiguration {
private final OverallStorageConfig config;
public StorageAutoConfiguration(OverallStorageConfig config) {
this.config = config;
if (config != null) {
loadConfig();
}
}
private void loadConfig() {
config.getConfigs().forEach(item -> {
String name = item.getName();
String type = item.getType();
IStorageAdapter adapter = StorageFactory.get(type);
Map<String, String> config = item.getConfig();
adapter.loadConfig(config);
StorageFactory.register(name, adapter);
});
}
}

View File

@@ -0,0 +1,15 @@
package com.ycwl.basic.storage.starter.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Component
@ConfigurationProperties(prefix = "storage")
@Data
public class OverallStorageConfig {
private List<StorageConfigItem> configs;
}

View File

@@ -0,0 +1,12 @@
package com.ycwl.basic.storage.starter.config;
import lombok.Data;
import java.util.Map;
@Data
public class StorageConfigItem {
private String name;
private String type;
private Map<String, String> config;
}

View File

@@ -0,0 +1,19 @@
package com.ycwl.basic.storage.tests;
import com.ycwl.basic.storage.StorageFactory;
import com.ycwl.basic.storage.adapters.AliOssAdapter;
import com.ycwl.basic.storage.adapters.IStorageAdapter;
import com.ycwl.basic.storage.enums.StorageType;
public class TestInitializationSpeed {
public static void main(String[] args) {
int i = 0;
long currentTimestamp = System.currentTimeMillis();
System.out.println("开始测试");
while (i++ < 100000000) {
// IStorageAdapter adapter = new AliOssAdapter();
StorageFactory.get(StorageType.ALI_OSS);
}
System.out.println("结束测试,耗时:" + (System.currentTimeMillis() - currentTimestamp) + "ms");
}
}

View File

@@ -0,0 +1,41 @@
package com.ycwl.basic.storage.utils;
import org.apache.commons.lang3.StringUtils;
public class StorageUtil {
public static String joinPath(String path, String subPath) {
if (StringUtils.isBlank(path)) {
return subPath;
}
if (subPath.startsWith("/")) {
subPath = subPath.substring(1);
}
if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
if (StringUtils.isBlank(subPath)) {
return path;
}
if (path.endsWith("/")) {
return path + subPath;
} else {
return path + "/" + subPath;
}
}
public static String joinPath(String ...names) {
String name = names[0];
for (int i = 1; i < names.length; i++) {
name = joinPath(name, names[i]);
}
return name;
}
public static String joinPath(String name, String ...names) {
for (String s : names) {
name = joinPath(name, s);
}
return name;
}
}