当前位置: 首页 > news >正文

Ruoyi-vue-plus-5.x第八篇文件管理与存储: 8.2 OSS云存储集成

👋 大家好,我是 阿问学长!专注于分享优质开源项目解析、毕业设计项目指导支持、幼小初高教辅资料推荐等,欢迎关注交流!🚀

OSS云存储集成

前言

云存储服务(Object Storage Service,OSS)是各大云服务商提供的海量、安全、低成本、高可靠的云存储服务。RuoYi-Vue-Plus框架支持多种云存储服务的集成,包括阿里云OSS、腾讯云COS、七牛云存储等。通过统一的存储接口,可以灵活切换不同的存储服务商,满足不同的业务需求。本文将详细介绍各种云存储服务的集成方式、存储策略配置以及多存储服务的统一管理。

阿里云OSS集成

阿里云OSS配置

/*** 阿里云OSS配置属性*/
@Data
@ConfigurationProperties(prefix = "oss.alibaba")
public class AlibabaOssProperties {/*** 是否启用*/private boolean enabled = false;/*** 访问端点*/private String endpoint;/*** 访问密钥ID*/private String accessKeyId;/*** 访问密钥密码*/private String accessKeySecret;/*** 存储桶名称*/private String bucketName;/*** 自定义域名*/private String domain;/*** 是否使用HTTPS*/private boolean https = true;/*** 连接超时时间(毫秒)*/private int connectionTimeout = 10000;/*** Socket超时时间(毫秒)*/private int socketTimeout = 50000;/*** 最大连接数*/private int maxConnections = 1024;/*** 最大错误重试次数*/private int maxErrorRetry = 3;/*** 预签名URL过期时间(秒)*/private long presignedUrlExpiration = 3600;
}/*** 阿里云OSS自动配置*/
@Configuration
@EnableConfigurationProperties(AlibabaOssProperties.class)
@ConditionalOnProperty(name = "oss.alibaba.enabled", havingValue = "true")
@Slf4j
public class AlibabaOssAutoConfiguration {@Autowiredprivate AlibabaOssProperties ossProperties;/*** 阿里云OSS客户端*/@Bean@ConditionalOnMissingBeanpublic OSS alibabaOssClient() {try {// 创建ClientConfigurationClientBuilderConfiguration config = new ClientBuilderConfiguration();config.setConnectionTimeout(ossProperties.getConnectionTimeout());config.setSocketTimeout(ossProperties.getSocketTimeout());config.setMaxConnections(ossProperties.getMaxConnections());config.setMaxErrorRetry(ossProperties.getMaxErrorRetry());config.setProtocol(ossProperties.isHttps() ? Protocol.HTTPS : Protocol.HTTP);// 创建OSS客户端OSS ossClient = new OSSClientBuilder().build(ossProperties.getEndpoint(),ossProperties.getAccessKeyId(),ossProperties.getAccessKeySecret(),config);log.info("阿里云OSS客户端初始化成功: endpoint={}, bucket={}", ossProperties.getEndpoint(), ossProperties.getBucketName());return ossClient;} catch (Exception e) {log.error("阿里云OSS客户端初始化失败", e);throw new RuntimeException("阿里云OSS客户端初始化失败", e);}}/*** 阿里云OSS模板*/@Bean@ConditionalOnMissingBeanpublic AlibabaOssTemplate alibabaOssTemplate(OSS ossClient) {return new AlibabaOssTemplate(ossClient, ossProperties);}
}/*** 阿里云OSS操作模板*/
@Component
@Slf4j
public class AlibabaOssTemplate implements OssTemplate {private final OSS ossClient;private final AlibabaOssProperties ossProperties;public AlibabaOssTemplate(OSS ossClient, AlibabaOssProperties ossProperties) {this.ossClient = ossClient;this.ossProperties = ossProperties;}@Overridepublic String upload(String objectName, InputStream inputStream, String contentType, long contentLength) {try {// 创建上传请求ObjectMetadata metadata = new ObjectMetadata();metadata.setContentType(contentType);metadata.setContentLength(contentLength);metadata.setCacheControl("max-age=31536000");PutObjectRequest request = new PutObjectRequest(ossProperties.getBucketName(), objectName, inputStream, metadata);// 执行上传PutObjectResult result = ossClient.putObject(request);log.debug("阿里云OSS上传成功: objectName={}, etag={}", objectName, result.getETag());return generateFileUrl(objectName);} catch (Exception e) {log.error("阿里云OSS上传失败: objectName={}", objectName, e);throw new RuntimeException("阿里云OSS上传失败", e);}}@Overridepublic InputStream download(String objectName) {try {OSSObject ossObject = ossClient.getObject(ossProperties.getBucketName(), objectName);return ossObject.getObjectContent();} catch (Exception e) {log.error("阿里云OSS下载失败: objectName={}", objectName, e);throw new RuntimeException("阿里云OSS下载失败", e);}}@Overridepublic void delete(String objectName) {try {ossClient.deleteObject(ossProperties.getBucketName(), objectName);log.debug("阿里云OSS删除成功: objectName={}", objectName);} catch (Exception e) {log.error("阿里云OSS删除失败: objectName={}", objectName, e);throw new RuntimeException("阿里云OSS删除失败", e);}}@Overridepublic void deleteMultiple(List<String> objectNames) {try {DeleteObjectsRequest request = new DeleteObjectsRequest(ossProperties.getBucketName());request.setKeys(objectNames);DeleteObjectsResult result = ossClient.deleteObjects(request);log.debug("阿里云OSS批量删除成功: count={}", result.getDeletedObjects().size());} catch (Exception e) {log.error("阿里云OSS批量删除失败", e);throw new RuntimeException("阿里云OSS批量删除失败", e);}}@Overridepublic boolean exists(String objectName) {try {return ossClient.doesObjectExist(ossProperties.getBucketName(), objectName);} catch (Exception e) {log.error("阿里云OSS检查文件存在失败: objectName={}", objectName, e);return false;}}@Overridepublic String getPresignedUrl(String objectName, long expiration) {try {Date expirationDate = new Date(System.currentTimeMillis() + expiration * 1000);URL url = ossClient.generatePresignedUrl(ossProperties.getBucketName(), objectName, expirationDate);return url.toString();} catch (Exception e) {log.error("阿里云OSS生成预签名URL失败: objectName={}", objectName, e);throw new RuntimeException("阿里云OSS生成预签名URL失败", e);}}@Overridepublic OssFileInfo getFileInfo(String objectName) {try {ObjectMetadata metadata = ossClient.getObjectMetadata(ossProperties.getBucketName(), objectName);return OssFileInfo.builder().objectName(objectName).size(metadata.getContentLength()).contentType(metadata.getContentType()).lastModified(metadata.getLastModified()).etag(metadata.getETag()).build();} catch (Exception e) {log.error("阿里云OSS获取文件信息失败: objectName={}", objectName, e);throw new RuntimeException("阿里云OSS获取文件信息失败", e);}}@Overridepublic String copy(String sourceObjectName, String targetObjectName) {try {CopyObjectRequest request = new CopyObjectRequest(ossProperties.getBucketName(), sourceObjectName,ossProperties.getBucketName(), targetObjectName);CopyObjectResult result = ossClient.copyObject(request);log.debug("阿里云OSS复制成功: {} -> {}, etag={}", sourceObjectName, targetObjectName, result.getETag());return generateFileUrl(targetObjectName);} catch (Exception e) {log.error("阿里云OSS复制失败: {} -> {}", sourceObjectName, targetObjectName, e);throw new RuntimeException("阿里云OSS复制失败", e);}}@Overridepublic List<OssFileInfo> listObjects(String prefix, int maxKeys) {try {ListObjectsRequest request = new ListObjectsRequest(ossProperties.getBucketName());request.setPrefix(prefix);request.setMaxKeys(maxKeys);ObjectListing listing = ossClient.listObjects(request);return listing.getObjectSummaries().stream().map(this::convertToFileInfo).collect(Collectors.toList());} catch (Exception e) {log.error("阿里云OSS列出对象失败: prefix={}", prefix, e);throw new RuntimeException("阿里云OSS列出对象失败", e);}}/*** 生成文件URL*/private String generateFileUrl(String objectName) {if (StringUtils.hasText(ossProperties.getDomain())) {return (ossProperties.isHttps() ? "https://" : "http://") + ossProperties.getDomain() + "/" + objectName;} else {return (ossProperties.isHttps() ? "https://" : "http://") + ossProperties.getBucketName() + "." + ossProperties.getEndpoint().replace("http://", "").replace("https://", "") + "/" + objectName;}}/*** 转换为文件信息*/private OssFileInfo convertToFileInfo(OSSObjectSummary summary) {return OssFileInfo.builder().objectName(summary.getKey()).size(summary.getSize()).lastModified(summary.getLastModified()).etag(summary.getETag()).build();}@PreDestroypublic void destroy() {if (ossClient != null) {ossClient.shutdown();log.info("阿里云OSS客户端已关闭");}}
}

腾讯云COS集成

腾讯云COS配置

/*** 腾讯云COS配置属性*/
@Data
@ConfigurationProperties(prefix = "oss.tencent")
public class TencentCosProperties {/*** 是否启用*/private boolean enabled = false;/*** 地域*/private String region;/*** 访问密钥ID*/private String secretId;/*** 访问密钥密码*/private String secretKey;/*** 存储桶名称*/private String bucketName;/*** 自定义域名*/private String domain;/*** 是否使用HTTPS*/private boolean https = true;/*** 连接超时时间(毫秒)*/private int connectionTimeout = 30000;/*** Socket超时时间(毫秒)*/private int socketTimeout = 30000;/*** 最大连接数*/private int maxConnections = 1024;/*** 预签名URL过期时间(秒)*/private long presignedUrlExpiration = 3600;
}/*** 腾讯云COS自动配置*/
@Configuration
@EnableConfigurationProperties(TencentCosProperties.class)
@ConditionalOnProperty(name = "oss.tencent.enabled", havingValue = "true")
@Slf4j
public class TencentCosAutoConfiguration {@Autowiredprivate TencentCosProperties cosProperties;/*** 腾讯云COS客户端*/@Bean@ConditionalOnMissingBeanpublic COSClient tencentCosClient() {try {// 创建认证信息COSCredentials credentials = new BasicCOSCredentials(cosProperties.getSecretId(), cosProperties.getSecretKey());// 创建客户端配置ClientConfig clientConfig = new ClientConfig(new Region(cosProperties.getRegion()));clientConfig.setHttpProtocol(cosProperties.isHttps() ? HttpProtocol.https : HttpProtocol.http);clientConfig.setConnectionTimeout(cosProperties.getConnectionTimeout());clientConfig.setSocketTimeout(cosProperties.getSocketTimeout());clientConfig.setMaxConnectionsCount(cosProperties.getMaxConnections());// 创建COS客户端COSClient cosClient = new COSClient(credentials, clientConfig);log.info("腾讯云COS客户端初始化成功: region={}, bucket={}", cosProperties.getRegion(), cosProperties.getBucketName());return cosClient;} catch (Exception e) {log.error("腾讯云COS客户端初始化失败", e);throw new RuntimeException("腾讯云COS客户端初始化失败", e);}}/*** 腾讯云COS模板*/@Bean@ConditionalOnMissingBeanpublic TencentCosTemplate tencentCosTemplate(COSClient cosClient) {return new TencentCosTemplate(cosClient, cosProperties);}
}/*** 腾讯云COS操作模板*/
@Component
@Slf4j
public class TencentCosTemplate implements OssTemplate {private final COSClient cosClient;private final TencentCosProperties cosProperties;public TencentCosTemplate(COSClient cosClient, TencentCosProperties cosProperties) {this.cosClient = cosClient;this.cosProperties = cosProperties;}@Overridepublic String upload(String objectName, InputStream inputStream, String contentType, long contentLength) {try {// 创建上传请求ObjectMetadata metadata = new ObjectMetadata();metadata.setContentType(contentType);metadata.setContentLength(contentLength);metadata.setCacheControl("max-age=31536000");PutObjectRequest request = new PutObjectRequest(cosProperties.getBucketName(), objectName, inputStream, metadata);// 执行上传PutObjectResult result = cosClient.putObject(request);log.debug("腾讯云COS上传成功: objectName={}, etag={}", objectName, result.getETag());return generateFileUrl(objectName);} catch (Exception e) {log.error("腾讯云COS上传失败: objectName={}", objectName, e);throw new RuntimeException("腾讯云COS上传失败", e);}}@Overridepublic InputStream download(String objectName) {try {COSObject cosObject = cosClient.getObject(cosProperties.getBucketName(), objectName);return cosObject.getObjectContent();} catch (Exception e) {log.error("腾讯云COS下载失败: objectName={}", objectName, e);throw new RuntimeException("腾讯云COS下载失败", e);}}@Overridepublic void delete(String objectName) {try {cosClient.deleteObject(cosProperties.getBucketName(), objectName);log.debug("腾讯云COS删除成功: objectName={}", objectName);} catch (Exception e) {log.error("腾讯云COS删除失败: objectName={}", objectName, e);throw new RuntimeException("腾讯云COS删除失败", e);}}@Overridepublic void deleteMultiple(List<String> objectNames) {try {DeleteObjectsRequest request = new DeleteObjectsRequest(cosProperties.getBucketName());List<DeleteObjectsRequest.KeyVersion> keys = objectNames.stream().map(DeleteObjectsRequest.KeyVersion::new).collect(Collectors.toList());request.setKeys(keys);DeleteObjectsResult result = cosClient.deleteObjects(request);log.debug("腾讯云COS批量删除成功: count={}", result.getDeletedObjects().size());} catch (Exception e) {log.error("腾讯云COS批量删除失败", e);throw new RuntimeException("腾讯云COS批量删除失败", e);}}@Overridepublic boolean exists(String objectName) {try {return cosClient.doesObjectExist(cosProperties.getBucketName(), objectName);} catch (Exception e) {log.error("腾讯云COS检查文件存在失败: objectName={}", objectName, e);return false;}}@Overridepublic String getPresignedUrl(String objectName, long expiration) {try {Date expirationDate = new Date(System.currentTimeMillis() + expiration * 1000);URL url = cosClient.generatePresignedUrl(cosProperties.getBucketName(), objectName, expirationDate, HttpMethodName.GET);return url.toString();} catch (Exception e) {log.error("腾讯云COS生成预签名URL失败: objectName={}", objectName, e);throw new RuntimeException("腾讯云COS生成预签名URL失败", e);}}@Overridepublic OssFileInfo getFileInfo(String objectName) {try {ObjectMetadata metadata = cosClient.getObjectMetadata(cosProperties.getBucketName(), objectName);return OssFileInfo.builder().objectName(objectName).size(metadata.getContentLength()).contentType(metadata.getContentType()).lastModified(metadata.getLastModified()).etag(metadata.getETag()).build();} catch (Exception e) {log.error("腾讯云COS获取文件信息失败: objectName={}", objectName, e);throw new RuntimeException("腾讯云COS获取文件信息失败", e);}}@Overridepublic String copy(String sourceObjectName, String targetObjectName) {try {CopyObjectRequest request = new CopyObjectRequest(cosProperties.getBucketName(), sourceObjectName,cosProperties.getBucketName(), targetObjectName);CopyObjectResult result = cosClient.copyObject(request);log.debug("腾讯云COS复制成功: {} -> {}, etag={}", sourceObjectName, targetObjectName, result.getETag());return generateFileUrl(targetObjectName);} catch (Exception e) {log.error("腾讯云COS复制失败: {} -> {}", sourceObjectName, targetObjectName, e);throw new RuntimeException("腾讯云COS复制失败", e);}}@Overridepublic List<OssFileInfo> listObjects(String prefix, int maxKeys) {try {ListObjectsRequest request = new ListObjectsRequest();request.setBucketName(cosProperties.getBucketName());request.setPrefix(prefix);request.setMaxKeys(maxKeys);ObjectListing listing = cosClient.listObjects(request);return listing.getObjectSummaries().stream().map(this::convertToFileInfo).collect(Collectors.toList());} catch (Exception e) {log.error("腾讯云COS列出对象失败: prefix={}", prefix, e);throw new RuntimeException("腾讯云COS列出对象失败", e);}}/*** 生成文件URL*/private String generateFileUrl(String objectName) {if (StringUtils.hasText(cosProperties.getDomain())) {return (cosProperties.isHttps() ? "https://" : "http://") + cosProperties.getDomain() + "/" + objectName;} else {return (cosProperties.isHttps() ? "https://" : "http://") + cosProperties.getBucketName() + ".cos." + cosProperties.getRegion() + ".myqcloud.com/" + objectName;}}/*** 转换为文件信息*/private OssFileInfo convertToFileInfo(COSObjectSummary summary) {return OssFileInfo.builder().objectName(summary.getKey()).size(summary.getSize()).lastModified(summary.getLastModified()).etag(summary.getETag()).build();}@PreDestroypublic void destroy() {if (cosClient != null) {cosClient.shutdown();log.info("腾讯云COS客户端已关闭");}}
}

七牛云存储集成

七牛云存储配置

/*** 七牛云存储配置属性*/
@Data
@ConfigurationProperties(prefix = "oss.qiniu")
public class QiniuOssProperties {/*** 是否启用*/private boolean enabled = false;/*** 访问密钥*/private String accessKey;/*** 秘密密钥*/private String secretKey;/*** 存储桶名称*/private String bucketName;/*** 存储区域*/private String region = "z0";/*** 自定义域名*/private String domain;/*** 是否使用HTTPS*/private boolean https = true;/*** 预签名URL过期时间(秒)*/private long presignedUrlExpiration = 3600;
}/*** 七牛云存储自动配置*/
@Configuration
@EnableConfigurationProperties(QiniuOssProperties.class)
@ConditionalOnProperty(name = "oss.qiniu.enabled", havingValue = "true")
@Slf4j
public class QiniuOssAutoConfiguration {@Autowiredprivate QiniuOssProperties ossProperties;/*** 七牛云认证*/@Bean@ConditionalOnMissingBeanpublic Auth qiniuAuth() {return Auth.create(ossProperties.getAccessKey(), ossProperties.getSecretKey());}/*** 七牛云配置*/@Bean@ConditionalOnMissingBeanpublic Configuration qiniuConfiguration() {Configuration config = new Configuration(getRegion(ossProperties.getRegion()));config.useHttpsDomains = ossProperties.isHttps();return config;}/*** 七牛云上传管理器*/@Bean@ConditionalOnMissingBeanpublic UploadManager qiniuUploadManager(Configuration configuration) {return new UploadManager(configuration);}/*** 七牛云存储管理器*/@Bean@ConditionalOnMissingBeanpublic BucketManager qiniuBucketManager(Auth auth, Configuration configuration) {return new BucketManager(auth, configuration);}/*** 七牛云OSS模板*/@Bean@ConditionalOnMissingBeanpublic QiniuOssTemplate qiniuOssTemplate(Auth auth, UploadManager uploadManager, BucketManager bucketManager, Configuration configuration) {return new QiniuOssTemplate(auth, uploadManager, bucketManager, configuration, ossProperties);}/*** 获取存储区域*/private Region getRegion(String regionCode) {switch (regionCode) {case "z0":return Region.region0();case "z1":return Region.region1();case "z2":return Region.region2();case "na0":return Region.regionNa0();case "as0":return Region.regionAs0();default:return Region.autoRegion();}}
}/*** 七牛云OSS操作模板*/
@Component
@Slf4j
public class QiniuOssTemplate implements OssTemplate {private final Auth auth;private final UploadManager uploadManager;private final BucketManager bucketManager;private final Configuration configuration;private final QiniuOssProperties ossProperties;public QiniuOssTemplate(Auth auth, UploadManager uploadManager, BucketManager bucketManager,Configuration configuration, QiniuOssProperties ossProperties) {this.auth = auth;this.uploadManager = uploadManager;this.bucketManager = bucketManager;this.configuration = configuration;this.ossProperties = ossProperties;}@Overridepublic String upload(String objectName, InputStream inputStream, String contentType, long contentLength) {try {// 生成上传凭证String uploadToken = auth.uploadToken(ossProperties.getBucketName(), objectName);// 执行上传Response response = uploadManager.put(inputStream, objectName, uploadToken, null, contentType);if (response.isOK()) {log.debug("七牛云OSS上传成功: objectName={}", objectName);return generateFileUrl(objectName);} else {throw new RuntimeException("七牛云OSS上传失败: " + response.error);}} catch (Exception e) {log.error("七牛云OSS上传失败: objectName={}", objectName, e);throw new RuntimeException("七牛云OSS上传失败", e);}}@Overridepublic InputStream download(String objectName) {try {String downloadUrl = getPresignedUrl(objectName, ossProperties.getPresignedUrlExpiration());// 通过HTTP下载文件URL url = new URL(downloadUrl);return url.openStream();} catch (Exception e) {log.error("七牛云OSS下载失败: objectName={}", objectName, e);throw new RuntimeException("七牛云OSS下载失败", e);}}@Overridepublic void delete(String objectName) {try {Response response = bucketManager.delete(ossProperties.getBucketName(), objectName);if (response.isOK()) {log.debug("七牛云OSS删除成功: objectName={}", objectName);} else {throw new RuntimeException("七牛云OSS删除失败: " + response.error);}} catch (Exception e) {log.error("七牛云OSS删除失败: objectName={}", objectName, e);throw new RuntimeException("七牛云OSS删除失败", e);}}@Overridepublic void deleteMultiple(List<String> objectNames) {try {BucketManager.BatchOperations batchOperations = new BucketManager.BatchOperations();for (String objectName : objectNames) {batchOperations.addDeleteOp(ossProperties.getBucketName(), objectName);}Response response = bucketManager.batch(batchOperations);if (response.isOK()) {log.debug("七牛云OSS批量删除成功: count={}", objectNames.size());} else {throw new RuntimeException("七牛云OSS批量删除失败: " + response.error);}} catch (Exception e) {log.error("七牛云OSS批量删除失败", e);throw new RuntimeException("七牛云OSS批量删除失败", e);}}@Overridepublic boolean exists(String objectName) {try {FileInfo fileInfo = bucketManager.stat(ossProperties.getBucketName(), objectName);return fileInfo != null;} catch (Exception e) {log.debug("七牛云OSS检查文件存在失败: objectName={}", objectName);return false;}}@Overridepublic String getPresignedUrl(String objectName, long expiration) {try {String baseUrl = generateFileUrl(objectName);if (StringUtils.hasText(ossProperties.getDomain())) {// 使用自定义域名,生成私有链接return auth.privateDownloadUrl(baseUrl, expiration);} else {// 使用默认域名return baseUrl;}} catch (Exception e) {log.error("七牛云OSS生成预签名URL失败: objectName={}", objectName, e);throw new RuntimeException("七牛云OSS生成预签名URL失败", e);}}@Overridepublic OssFileInfo getFileInfo(String objectName) {try {FileInfo fileInfo = bucketManager.stat(ossProperties.getBucketName(), objectName);return OssFileInfo.builder().objectName(objectName).size(fileInfo.fsize).contentType(fileInfo.mimeType).lastModified(new Date(fileInfo.putTime / 10000)).etag(fileInfo.hash).build();} catch (Exception e) {log.error("七牛云OSS获取文件信息失败: objectName={}", objectName, e);throw new RuntimeException("七牛云OSS获取文件信息失败", e);}}@Overridepublic String copy(String sourceObjectName, String targetObjectName) {try {Response response = bucketManager.copy(ossProperties.getBucketName(), sourceObjectName,ossProperties.getBucketName(), targetObjectName);if (response.isOK()) {log.debug("七牛云OSS复制成功: {} -> {}", sourceObjectName, targetObjectName);return generateFileUrl(targetObjectName);} else {throw new RuntimeException("七牛云OSS复制失败: " + response.error);}} catch (Exception e) {log.error("七牛云OSS复制失败: {} -> {}", sourceObjectName, targetObjectName, e);throw new RuntimeException("七牛云OSS复制失败", e);}}@Overridepublic List<OssFileInfo> listObjects(String prefix, int maxKeys) {try {FileListing listing = bucketManager.listFiles(ossProperties.getBucketName(), prefix, null, maxKeys, null);return Arrays.stream(listing.items).map(this::convertToFileInfo).collect(Collectors.toList());} catch (Exception e) {log.error("七牛云OSS列出对象失败: prefix={}", prefix, e);throw new RuntimeException("七牛云OSS列出对象失败", e);}}/*** 生成文件URL*/private String generateFileUrl(String objectName) {if (StringUtils.hasText(ossProperties.getDomain())) {return (ossProperties.isHttps() ? "https://" : "http://") + ossProperties.getDomain() + "/" + objectName;} else {// 使用默认域名(需要根据实际情况调整)return (ossProperties.isHttps() ? "https://" : "http://") + ossProperties.getBucketName() + ".qiniucdn.com/" + objectName;}}/*** 转换为文件信息*/private OssFileInfo convertToFileInfo(FileInfo fileInfo) {return OssFileInfo.builder().objectName(fileInfo.key).size(fileInfo.fsize).contentType(fileInfo.mimeType).lastModified(new Date(fileInfo.putTime / 10000)).etag(fileInfo.hash).build();}
}

存储策略配置

统一存储接口

/*** OSS存储模板接口*/
public interface OssTemplate {/*** 上传文件*/String upload(String objectName, InputStream inputStream, String contentType, long contentLength);/*** 下载文件*/InputStream download(String objectName);/*** 删除文件*/void delete(String objectName);/*** 批量删除文件*/void deleteMultiple(List<String> objectNames);/*** 检查文件是否存在*/boolean exists(String objectName);/*** 获取预签名URL*/String getPresignedUrl(String objectName, long expiration);/*** 获取文件信息*/OssFileInfo getFileInfo(String objectName);/*** 复制文件*/String copy(String sourceObjectName, String targetObjectName);/*** 列出对象*/List<OssFileInfo> listObjects(String prefix, int maxKeys);
}/*** OSS文件信息*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OssFileInfo {/*** 对象名称*/private String objectName;/*** 文件大小*/private long size;/*** 内容类型*/private String contentType;/*** 最后修改时间*/private Date lastModified;/*** ETag*/private String etag;/*** 格式化大小*/public String getFormattedSize() {return FileUtils.formatFileSize(size);}
}/*** OSS存储策略配置*/
@Data
@ConfigurationProperties(prefix = "oss.strategy")
public class OssStrategyProperties {/*** 默认存储服务*/private String defaultService = "minio";/*** 存储策略映射*/private Map<String, String> categoryMapping = new HashMap<>();/*** 是否启用多存储服务*/private boolean multiServiceEnabled = false;/*** 存储服务权重配置*/private Map<String, Integer> serviceWeights = new HashMap<>();
}/*** OSS存储策略管理器*/
@Component
@Slf4j
public class OssStrategyManager {@Autowiredprivate OssStrategyProperties strategyProperties;@Autowired(required = false)private MinioTemplate minioTemplate;@Autowired(required = false)private AlibabaOssTemplate alibabaOssTemplate;@Autowired(required = false)private TencentCosTemplate tencentCosTemplate;@Autowired(required = false)private QiniuOssTemplate qiniuOssTemplate;private final Map<String, OssTemplate> templateMap = new HashMap<>();@PostConstructpublic void init() {// 注册可用的存储模板if (minioTemplate != null) {templateMap.put("minio", minioTemplate);log.info("注册MinIO存储模板");}if (alibabaOssTemplate != null) {templateMap.put("alibaba", alibabaOssTemplate);log.info("注册阿里云OSS存储模板");}if (tencentCosTemplate != null) {templateMap.put("tencent", tencentCosTemplate);log.info("注册腾讯云COS存储模板");}if (qiniuOssTemplate != null) {templateMap.put("qiniu", qiniuOssTemplate);log.info("注册七牛云存储模板");}log.info("OSS存储策略管理器初始化完成,可用服务: {}", templateMap.keySet());}/*** 根据类别获取存储模板*/public OssTemplate getTemplate(String category) {String serviceName = getServiceName(category);OssTemplate template = templateMap.get(serviceName);if (template == null) {throw new RuntimeException("未找到存储服务: " + serviceName);}return template;}/*** 获取默认存储模板*/public OssTemplate getDefaultTemplate() {return getTemplate(null);}/*** 根据类别获取服务名称*/private String getServiceName(String category) {if (StringUtils.hasText(category)) {String mappedService = strategyProperties.getCategoryMapping().get(category);if (StringUtils.hasText(mappedService)) {return mappedService;}}return strategyProperties.getDefaultService();}/*** 获取所有可用的存储服务*/public Set<String> getAvailableServices() {return templateMap.keySet();}/*** 检查服务是否可用*/public boolean isServiceAvailable(String serviceName) {return templateMap.containsKey(serviceName);}
}

总结

本文详细介绍了OSS云存储集成,包括:

  1. 阿里云OSS集成:配置属性、自动配置、操作模板、文件管理
  2. 腾讯云COS集成:配置属性、客户端配置、操作模板、API调用
  3. 七牛云存储集成:配置属性、认证配置、操作模板、文件操作
  4. 存储策略配置:统一存储接口、策略管理器、多服务支持

通过统一的存储接口和策略配置,可以灵活地在不同的云存储服务之间切换,满足不同的业务需求和成本考虑。

在下一篇文章中,我们将探讨文件处理功能。

参考资料

  • 阿里云OSS Java SDK
  • 腾讯云COS Java SDK
  • 七牛云存储 Java SDK

文章转载自:

http://QqTLrxeN.hyhqd.cn
http://PARJESH9.hyhqd.cn
http://xhHuIawA.hyhqd.cn
http://FRB4eLJ8.hyhqd.cn
http://hSe2xsgz.hyhqd.cn
http://xeKFNLJl.hyhqd.cn
http://JNP1kcdW.hyhqd.cn
http://fOwgEvkW.hyhqd.cn
http://RN5CF8WU.hyhqd.cn
http://b6SCacRX.hyhqd.cn
http://np6ZKqIg.hyhqd.cn
http://4MMkZgkz.hyhqd.cn
http://7RXy9jHv.hyhqd.cn
http://BfwvmPnG.hyhqd.cn
http://FSTIMCNV.hyhqd.cn
http://kWKu3kjs.hyhqd.cn
http://f73oqy08.hyhqd.cn
http://PgC4wgTe.hyhqd.cn
http://65HZsNPv.hyhqd.cn
http://fQmkckE9.hyhqd.cn
http://MHPh2VvC.hyhqd.cn
http://V1aDtoHV.hyhqd.cn
http://fgQwJrvK.hyhqd.cn
http://ykucdmMh.hyhqd.cn
http://zuFhlyKn.hyhqd.cn
http://M9eqY9J3.hyhqd.cn
http://zMWcXYKA.hyhqd.cn
http://uTik7Dsz.hyhqd.cn
http://peVHjqAx.hyhqd.cn
http://eqfsb9Gv.hyhqd.cn
http://www.dtcms.com/a/380651.html

相关文章:

  • 解决:NVIDIA-SMI couldn‘t find libnvidia-ml.so library in your system.
  • 【LLM】VLLM:容器运行 ModelScope 模型
  • HarmonyOS 应用开发深度解析:基于 Stage 模型与 ArkUI 的跨组件状态共享最佳实践
  • TOGAF——战术性调整,战略性变更
  • 【计算机 UTF-8 转换为本地编码的含义】
  • 当人工智能遇上知识检索:RAG技术的深度解析与实践探索
  • 在线商城管理系统功能清单的系统设计
  • SLAM 系统设计是如何保证前端(tracking/VO)和后端(优化/BA/图优化)如何同步实时性思路汇总思考
  • 代码随想录二刷之“动态规划”~GO
  • zynq arm全局计时器和私有定时器
  • TCP套接字的使用
  • 红日靶场(三)——个人笔记
  • Linux 进程和线程基础知识解析
  • MySQL 查询不正确身份证号的方法
  • 淘宝商品详情 API 的安全强化与生态协同创新路径
  • 全志A133 android10 secure boot 安全启动
  • 储能电站的监控运维软件推荐,降低运营成本
  • 麒麟v10系统内存不足
  • fpga图像处理
  • 使用netstat 获取各Oracle数据库实例对应应用IP地址脚本
  • QT M/V架构开发实战:QAbstractItemModel介绍
  • PHP 与 WebAssembly 的 “天然隔阂”
  • QML 的第一步
  • IP验证学习之env集成编写
  • Android8 binder源码学习分析笔记(四)——ServiceManager启动
  • fastapi搭建Ansible Playbook执行器
  • 第四阶段C#通讯开发-1:通讯基础理论,串口,通讯模式,单位转换,代码示例
  • 微信小程序——云函数【使用使用注意事项】
  • 【java】常见排序算法详解
  • HarmonyOS 应用开发深度解析:基于声明式UI的现代化状态管理实践