From 2e7cbb6e839a3247094c44867a580719aa2c3247 Mon Sep 17 00:00:00 2001 From: Kytrun Date: Fri, 4 Nov 2022 16:32:00 +0800 Subject: [PATCH 1/9] =?UTF-8?q?feat:=20=E8=B0=B7=E6=AD=8C=E4=BA=91?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E5=AD=98=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- docs/README.md | 2 +- ...30\345\202\250\345\271\263\345\217\260.md" | 1 + ...53\351\200\237\345\205\245\351\227\250.md" | 22 +++ spring-file-storage-test/pom.xml | 14 ++ .../src/main/resources/application.yml | 8 + spring-file-storage/pom.xml | 9 + .../storage/FileStorageAutoConfiguration.java | 20 +++ .../file/storage/FileStorageProperties.java | 28 ++++ .../storage/platform/GoogleCloudStorage.java | 157 ++++++++++++++++++ 10 files changed, 261 insertions(+), 2 deletions(-) create mode 100644 spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/platform/GoogleCloudStorage.java diff --git a/README.md b/README.md index 73cac737..ceafd7a3 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ AWS S3、金山云 KS3、美团云 MSS、京东云 OSS、天翼云 OOS、移动 查看 [所有支持的存储平台](https://spring-file-storage.xuyanwu.cn/#/存储平台) -后续即将支持 谷歌云存储、Samba、NFS +后续即将支持 Samba、NFS > 通过 WebDAV 连接到 Alist 后,可以使用百度网盘、天翼云盘、阿里云盘、迅雷网盘等常见存储服务,[查看 Alist 支持的存储平台](https://alist-doc.nn.ci/docs/webdav) diff --git a/docs/README.md b/docs/README.md index abb00bb5..a044f1bc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -30,7 +30,7 @@ AWS S3、金山云 KS3、美团云 MSS、京东云 OSS、天翼云 OOS、移动 查看 [所有支持的存储平台](存储平台) -后续即将支持 谷歌云存储、Samba、NFS +后续即将支持 Samba、NFS > 通过 WebDAV 连接到 Alist 后,可以使用百度网盘、天翼云盘、阿里云盘、迅雷网盘等常见存储服务,[查看 Alist 支持的存储平台](https://alist-doc.nn.ci/docs/webdav) diff --git "a/docs/\345\255\230\345\202\250\345\271\263\345\217\260.md" "b/docs/\345\255\230\345\202\250\345\271\263\345\217\260.md" index f1d6b695..8235e3c8 100644 --- "a/docs/\345\255\230\345\202\250\345\271\263\345\217\260.md" +++ "b/docs/\345\255\230\345\202\250\345\271\263\345\217\260.md" @@ -34,6 +34,7 @@ | 平安云 OBS | × | √ | [查看](https://yun.pingan.com/ssr/help/storage/obs/OBS_SDK_.Java_SDK_) | | 首云 OSS | × | √ | [查看](http://www.capitalonline.net.cn/zh-cn/service/distribution/oss-new/#product-adv) | | IBM COS | × | √ | [查看](https://cloud.ibm.com/docs/cloud-object-storage?topic=cloud-object-storage-compatibility-api) | +| 谷歌云存储 | √ | × | - | | 其它兼容 S3 协议的平台 | × | √ | - | 如果想通 AWS S3 SDK 使用对应的存储平台,直接将配置写在 ASW S3 中。 diff --git "a/docs/\345\277\253\351\200\237\345\205\245\351\227\250.md" "b/docs/\345\277\253\351\200\237\345\205\245\351\227\250.md" index 63980864..69306b76 100644 --- "a/docs/\345\277\253\351\200\237\345\205\245\351\227\250.md" +++ "b/docs/\345\277\253\351\200\237\345\205\245\351\227\250.md" @@ -97,6 +97,20 @@ 5.10 + + + com.google.cloud + google-cloud-storage + 2.14.0 + + + + + com.google.guava + guava + 31.1-jre + + ``` @@ -223,6 +237,14 @@ spring: domain: ?? # 访问域名,注意“/”结尾,例如:https://file.abc.com/ base-path: webdav/ # 基础路径 storage-path: / # 存储路径,可以配合 Nginx 实现访问,注意“/”结尾,默认“/” + google-cloud: # 谷歌云存储 + - platform: google-1 # 存储平台标识 + enable-storage: true # 启用存储 + project-id: ?? # 项目 id + bucket-name: ?? + credentials-location: /deploy/example-key.json # 授权 key json 文件路径 + domain: ?? # 访问域名,注意“/”结尾,例如:https://storage.googleapis.com/test-bucket/ + base-path: hy/ # 基础路径 ``` 注意配置每个平台前面都有个`-`号,通过以下方式可以配置多个 diff --git a/spring-file-storage-test/pom.xml b/spring-file-storage-test/pom.xml index ef28429e..1bb1d91b 100644 --- a/spring-file-storage-test/pom.xml +++ b/spring-file-storage-test/pom.xml @@ -106,6 +106,20 @@ 3.22.3.1 + + + com.google.cloud + google-cloud-storage + 2.14.0 + + + + + com.google.guava + guava + 31.1-jre + + cn.hutool diff --git a/spring-file-storage-test/src/main/resources/application.yml b/spring-file-storage-test/src/main/resources/application.yml index 545c1e9d..d950f6d7 100644 --- a/spring-file-storage-test/src/main/resources/application.yml +++ b/spring-file-storage-test/src/main/resources/application.yml @@ -129,3 +129,11 @@ spring: domain: ?? # 访问域名,注意“/”结尾,例如:https://file.abc.com/ base-path: webdav/ # 基础路径 storage-path: / # 存储路径,上传的文件都会存储在这个路径下面,默认“/”,注意“/”结尾 + google-cloud: # 谷歌云存储 + - platform: google-1 # 存储平台标识 + enable-storage: true # 启用存储 + project-id: ?? # 项目 id + bucket-name: ?? + credentials-location: /deploy/example-key.json # 授权 key json 文件路径 + domain: ?? # 访问域名,注意“/”结尾,例如:https://storage.googleapis.com/test-bucket/ + base-path: hy/ # 基础路径 diff --git a/spring-file-storage/pom.xml b/spring-file-storage/pom.xml index 038dcade..34e7856e 100644 --- a/spring-file-storage/pom.xml +++ b/spring-file-storage/pom.xml @@ -127,6 +127,15 @@ true + + + com.google.cloud + google-cloud-storage + 2.14.0 + provided + true + + cn.hutool diff --git a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageAutoConfiguration.java b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageAutoConfiguration.java index e8f81c55..47f27034 100644 --- a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageAutoConfiguration.java +++ b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageAutoConfiguration.java @@ -323,6 +323,23 @@ public List webDavFileStorageList() { return storage; }).filter(Objects::nonNull).collect(Collectors.toList()); } + + @Bean + @ConditionalOnClass(name = "com.google.cloud.storage.Storage") + public List googleCloudStorageList() { + return properties.getGoogleCloud().stream().map(googleCloud -> { + if (!googleCloud.getEnableStorage()) return null; + log.info("加载存储平台:{}", googleCloud.getPlatform()); + GoogleCloudStorage storage = new GoogleCloudStorage(); + storage.setPlatform(googleCloud.getPlatform()); + storage.setProjectId(googleCloud.getProjectId()); + storage.setBucketName(googleCloud.getBucketName()); + storage.setCredentialsLocation(googleCloud.getCredentialsLocation()); + storage.setDomain(googleCloud.getDomain()); + storage.setBasePath(googleCloud.getBasePath()); + return storage; + }).filter(Objects::nonNull).collect(Collectors.toList()); + } /** * 当没有找到 FileRecorder 时使用默认的 FileRecorder @@ -395,6 +412,9 @@ public void initDetect() { if (CollUtil.isNotEmpty(properties.getAwsS3()) && doesNotExistClass("com.github.sardine.Sardine")) { log.warn(template," WebDAV "); } + if (CollUtil.isNotEmpty(properties.getGoogleCloud()) && doesNotExistClass("com.google.cloud.storage.Storage")) { + log.warn(template, " 谷歌云存储 "); + } } /** diff --git a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageProperties.java b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageProperties.java index 8593228e..989e6172 100644 --- a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageProperties.java +++ b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageProperties.java @@ -81,6 +81,11 @@ public class FileStorageProperties { */ private List WebDav = new ArrayList<>(); + /** + * 谷歌云存储 + */ + private List googleCloud = new ArrayList<>(); + /** * 本地存储 */ @@ -523,4 +528,27 @@ public static class WebDAV { */ private String storagePath = "/"; } + + @Data + public static class GoogleCloud { + private String projectId; + private String credentialsLocation; + private String bucketName; + /** + * 访问域名 + */ + private String domain = ""; + /** + * 启用存储 + */ + private Boolean enableStorage = false; + /** + * 存储平台 + */ + private String platform = ""; + /** + * 基础路径 + */ + private String basePath = ""; + } } diff --git a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/platform/GoogleCloudStorage.java b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/platform/GoogleCloudStorage.java new file mode 100644 index 00000000..c81e8a37 --- /dev/null +++ b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/platform/GoogleCloudStorage.java @@ -0,0 +1,157 @@ +package cn.xuyanwu.spring.file.storage.platform; + +import cn.hutool.core.util.StrUtil; +import cn.xuyanwu.spring.file.storage.FileInfo; +import cn.xuyanwu.spring.file.storage.UploadPretreatment; +import cn.xuyanwu.spring.file.storage.exception.FileStorageRuntimeException; +import com.google.auth.oauth2.ServiceAccountCredentials; +import com.google.cloud.ReadChannel; +import com.google.cloud.storage.*; +import lombok.Getter; +import lombok.Setter; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.channels.Channels; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.List; +import java.util.function.Consumer; + +/** + * @author Kytrun + * @version 1.0 + * @date 2022/11/4 9:56 + */ +@Getter +@Setter +public class GoogleCloudStorage implements FileStorage { + private String projectId; + private String bucketName; + private String credentialsLocation; + /* 基础路径 */ + private String basePath; + /* 存储平台 */ + private String platform; + /* 访问域名 */ + private String domain; + + private Storage client; + + /** + * 单例模式运行,不需要每次使用完再销毁了 + */ + public Storage getClient() { + if (client == null) { + ServiceAccountCredentials credentialsFromStream; + try { + InputStream stream = Files.newInputStream(Paths.get(credentialsLocation)); + credentialsFromStream = ServiceAccountCredentials.fromStream(stream); + } catch (IOException e) { + throw new FileStorageRuntimeException("Google Cloud Platform 授权 key 文件获取失败!credentialsLocation:" + credentialsLocation); + } + List scopes = Collections.singletonList("https://www.googleapis.com/auth/cloud-platform"); + ServiceAccountCredentials credentials = credentialsFromStream.toBuilder().setScopes(scopes).build(); + StorageOptions storageOptions = StorageOptions.newBuilder().setProjectId(projectId).setCredentials(credentials).build(); + client = storageOptions.getService(); + } + return client; + } + + + @Override + public void close() { + if (client != null) { + try { + client.close(); + } catch (Exception e) { + throw new FileStorageRuntimeException(e); + } + client = null; + } + } + + @Override + public boolean save(FileInfo fileInfo, UploadPretreatment pre) { + String newFileKey = basePath + fileInfo.getPath() + fileInfo.getFilename(); + fileInfo.setBasePath(basePath); + fileInfo.setUrl(domain + newFileKey); + Storage client = getClient(); + + BlobId blobId = BlobId.of(bucketName, newFileKey); + BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType(fileInfo.getContentType()).build(); + try (InputStream in = pre.getFileWrapper().getInputStream()) { + // 上传原文件 + client.createFrom(blobInfo, in); + //上传缩略图 + byte[] thumbnailBytes = pre.getThumbnailBytes(); + if (thumbnailBytes != null) { + String newThFileKey = basePath + fileInfo.getPath() + fileInfo.getThFilename(); + fileInfo.setThUrl(domain + newThFileKey); + BlobId thBlobId = BlobId.of(bucketName, newThFileKey); + BlobInfo thBlobInfo = BlobInfo.newBuilder(thBlobId).setContentType(fileInfo.getThContentType()).build(); + client.createFrom(thBlobInfo, new ByteArrayInputStream(thumbnailBytes)); + } + return true; + } catch (IOException e) { + checkAndDelete(newFileKey); + throw new FileStorageRuntimeException("文件上传失败!platform:" + platform + ",filename:" + fileInfo.getOriginalFilename(), e); + } + } + + + /** + * 检查并删除对象 + * Source Example + * + * @param fileKey 对象 key + */ + private void checkAndDelete(String fileKey) { + Storage client = getClient(); + Blob blob = client.get(bucketName, fileKey); + if (blob != null) { + Storage.BlobSourceOption precondition = Storage.BlobSourceOption.generationMatch(blob.getGeneration()); + client.delete(bucketName, fileKey, precondition); + } + } + + @Override + public boolean delete(FileInfo fileInfo) { + //删除缩略图 + if (fileInfo.getThFilename() != null) { + checkAndDelete(fileInfo.getBasePath() + fileInfo.getPath() + fileInfo.getThFilename()); + } + checkAndDelete(fileInfo.getBasePath() + fileInfo.getPath() + fileInfo.getFilename()); + return true; + } + + @Override + public boolean exists(FileInfo fileInfo) { + Storage client = getClient(); + BlobId blobId = BlobId.of(bucketName, fileInfo.getBasePath() + fileInfo.getPath() + fileInfo.getFilename()); + return client.get(blobId) != null; + } + + @Override + public void download(FileInfo fileInfo, Consumer consumer) { + Storage client = getClient(); + BlobId blobId = BlobId.of(bucketName, fileInfo.getBasePath() + fileInfo.getPath() + fileInfo.getFilename()); + ReadChannel readChannel = client.reader(blobId); + InputStream in = Channels.newInputStream(readChannel); + consumer.accept(in); + } + + @Override + public void downloadTh(FileInfo fileInfo, Consumer consumer) { + if (StrUtil.isBlank(fileInfo.getThFilename())) { + throw new FileStorageRuntimeException("缩略图文件下载失败,文件不存在!fileInfo:" + fileInfo); + } + Storage client = getClient(); + BlobId thBlobId = BlobId.of(bucketName, fileInfo.getBasePath() + fileInfo.getPath() + fileInfo.getThFilename()); + ReadChannel readChannel = client.reader(thBlobId); + InputStream in = Channels.newInputStream(readChannel); + consumer.accept(in); + } +} From cb94bae27a5db4d8755a5bd023bb88632e02a55e Mon Sep 17 00:00:00 2001 From: Kytrun Date: Wed, 9 Nov 2022 12:40:36 +0800 Subject: [PATCH 2/9] =?UTF-8?q?perf:=20=E9=85=8D=E7=BD=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E8=B7=AF=E5=BE=84=E4=BD=BF=E7=94=A8=20Resource?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=20classpath=EF=BC=8Cfile=EF=BC=8Cht?= =?UTF-8?q?tp=20=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...5\277\253\351\200\237\345\205\245\351\227\250.md" | 2 +- .../src/main/resources/application.yml | 2 +- .../spring/file/storage/FileStorageProperties.java | 3 ++- .../file/storage/platform/GoogleCloudStorage.java | 12 +++++++----- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git "a/docs/\345\277\253\351\200\237\345\205\245\351\227\250.md" "b/docs/\345\277\253\351\200\237\345\205\245\351\227\250.md" index 69306b76..273294f5 100644 --- "a/docs/\345\277\253\351\200\237\345\205\245\351\227\250.md" +++ "b/docs/\345\277\253\351\200\237\345\205\245\351\227\250.md" @@ -242,7 +242,7 @@ spring: enable-storage: true # 启用存储 project-id: ?? # 项目 id bucket-name: ?? - credentials-location: /deploy/example-key.json # 授权 key json 文件路径 + credentials-location: file:/deploy/example-key.json # 授权 key json 文件路径,支持 file, classpath, http 等,参考 https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/resources.html#:~:text=Table%C2%A06.1.%C2%A0Resource%20strings domain: ?? # 访问域名,注意“/”结尾,例如:https://storage.googleapis.com/test-bucket/ base-path: hy/ # 基础路径 ``` diff --git a/spring-file-storage-test/src/main/resources/application.yml b/spring-file-storage-test/src/main/resources/application.yml index d950f6d7..b2ba18f1 100644 --- a/spring-file-storage-test/src/main/resources/application.yml +++ b/spring-file-storage-test/src/main/resources/application.yml @@ -134,6 +134,6 @@ spring: enable-storage: true # 启用存储 project-id: ?? # 项目 id bucket-name: ?? - credentials-location: /deploy/example-key.json # 授权 key json 文件路径 + credentials-location: file:/deploy/example-key.json # 授权 key json 文件路径,支持 file, classpath, http 等,参考 https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/resources.html#:~:text=Table%C2%A06.1.%C2%A0Resource%20strings domain: ?? # 访问域名,注意“/”结尾,例如:https://storage.googleapis.com/test-bucket/ base-path: hy/ # 基础路径 diff --git a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageProperties.java b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageProperties.java index 989e6172..0f602f02 100644 --- a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageProperties.java +++ b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageProperties.java @@ -3,6 +3,7 @@ import lombok.Data; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.core.io.Resource; import org.springframework.stereotype.Component; import java.nio.charset.Charset; @@ -532,7 +533,7 @@ public static class WebDAV { @Data public static class GoogleCloud { private String projectId; - private String credentialsLocation; + private Resource credentialsLocation; private String bucketName; /** * 访问域名 diff --git a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/platform/GoogleCloudStorage.java b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/platform/GoogleCloudStorage.java index c81e8a37..1f9fb5f6 100644 --- a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/platform/GoogleCloudStorage.java +++ b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/platform/GoogleCloudStorage.java @@ -9,13 +9,12 @@ import com.google.cloud.storage.*; import lombok.Getter; import lombok.Setter; +import org.springframework.core.io.Resource; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.channels.Channels; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.Collections; import java.util.List; import java.util.function.Consumer; @@ -30,7 +29,11 @@ public class GoogleCloudStorage implements FileStorage { private String projectId; private String bucketName; - private String credentialsLocation; + /** + * 配置文件路径,支持 classpath, file, http 等 + * 参考 Resource + */ + private Resource credentialsLocation; /* 基础路径 */ private String basePath; /* 存储平台 */ @@ -47,8 +50,7 @@ public Storage getClient() { if (client == null) { ServiceAccountCredentials credentialsFromStream; try { - InputStream stream = Files.newInputStream(Paths.get(credentialsLocation)); - credentialsFromStream = ServiceAccountCredentials.fromStream(stream); + credentialsFromStream = ServiceAccountCredentials.fromStream(credentialsLocation.getInputStream()); } catch (IOException e) { throw new FileStorageRuntimeException("Google Cloud Platform 授权 key 文件获取失败!credentialsLocation:" + credentialsLocation); } From 7f1628f760714b51a1cfc1a6a7b58555a1482d97 Mon Sep 17 00:00:00 2001 From: xuyanwu <1171736840@qq.com> Date: Wed, 9 Nov 2022 16:08:21 +0800 Subject: [PATCH 3/9] =?UTF-8?q?update:=E8=B0=B7=E6=AD=8C=E4=BA=91=E5=AD=98?= =?UTF-8?q?=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\277\253\351\200\237\345\205\245\351\227\250.md" | 2 +- .../src/main/resources/application.yml | 2 +- .../file/storage/FileStorageAutoConfiguration.java | 4 ++-- .../spring/file/storage/FileStorageProperties.java | 6 ++++-- .../file/storage/platform/GoogleCloudStorage.java | 13 ++++++------- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git "a/docs/\345\277\253\351\200\237\345\205\245\351\227\250.md" "b/docs/\345\277\253\351\200\237\345\205\245\351\227\250.md" index 273294f5..4321e20f 100644 --- "a/docs/\345\277\253\351\200\237\345\205\245\351\227\250.md" +++ "b/docs/\345\277\253\351\200\237\345\205\245\351\227\250.md" @@ -242,7 +242,7 @@ spring: enable-storage: true # 启用存储 project-id: ?? # 项目 id bucket-name: ?? - credentials-location: file:/deploy/example-key.json # 授权 key json 文件路径,支持 file, classpath, http 等,参考 https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/resources.html#:~:text=Table%C2%A06.1.%C2%A0Resource%20strings + credentials-path: file:/deploy/example-key.json # 授权 key json 路径,兼容Spring的ClassPath路径、文件路径、HTTP路径等 domain: ?? # 访问域名,注意“/”结尾,例如:https://storage.googleapis.com/test-bucket/ base-path: hy/ # 基础路径 ``` diff --git a/spring-file-storage-test/src/main/resources/application.yml b/spring-file-storage-test/src/main/resources/application.yml index b2ba18f1..ba790a6e 100644 --- a/spring-file-storage-test/src/main/resources/application.yml +++ b/spring-file-storage-test/src/main/resources/application.yml @@ -134,6 +134,6 @@ spring: enable-storage: true # 启用存储 project-id: ?? # 项目 id bucket-name: ?? - credentials-location: file:/deploy/example-key.json # 授权 key json 文件路径,支持 file, classpath, http 等,参考 https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/resources.html#:~:text=Table%C2%A06.1.%C2%A0Resource%20strings + credentials-path: file:/deploy/example-key.json # 授权 key json 路径,兼容Spring的ClassPath路径、文件路径、HTTP路径等 domain: ?? # 访问域名,注意“/”结尾,例如:https://storage.googleapis.com/test-bucket/ base-path: hy/ # 基础路径 diff --git a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageAutoConfiguration.java b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageAutoConfiguration.java index 47f27034..c71439b8 100644 --- a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageAutoConfiguration.java +++ b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageAutoConfiguration.java @@ -323,7 +323,7 @@ public List webDavFileStorageList() { return storage; }).filter(Objects::nonNull).collect(Collectors.toList()); } - + @Bean @ConditionalOnClass(name = "com.google.cloud.storage.Storage") public List googleCloudStorageList() { @@ -334,7 +334,7 @@ public List googleCloudStorageList() { storage.setPlatform(googleCloud.getPlatform()); storage.setProjectId(googleCloud.getProjectId()); storage.setBucketName(googleCloud.getBucketName()); - storage.setCredentialsLocation(googleCloud.getCredentialsLocation()); + storage.setCredentialsPath(googleCloud.getCredentialsPath()); storage.setDomain(googleCloud.getDomain()); storage.setBasePath(googleCloud.getBasePath()); return storage; diff --git a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageProperties.java b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageProperties.java index 0f602f02..6957d167 100644 --- a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageProperties.java +++ b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageProperties.java @@ -3,7 +3,6 @@ import lombok.Data; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.core.io.Resource; import org.springframework.stereotype.Component; import java.nio.charset.Charset; @@ -533,7 +532,10 @@ public static class WebDAV { @Data public static class GoogleCloud { private String projectId; - private Resource credentialsLocation; + /** + * 证书路径,兼容Spring的ClassPath路径、文件路径、HTTP路径等 + */ + private String credentialsPath; private String bucketName; /** * 访问域名 diff --git a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/platform/GoogleCloudStorage.java b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/platform/GoogleCloudStorage.java index 1f9fb5f6..d79a758c 100644 --- a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/platform/GoogleCloudStorage.java +++ b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/platform/GoogleCloudStorage.java @@ -1,6 +1,7 @@ package cn.xuyanwu.spring.file.storage.platform; import cn.hutool.core.util.StrUtil; +import cn.hutool.core.util.URLUtil; import cn.xuyanwu.spring.file.storage.FileInfo; import cn.xuyanwu.spring.file.storage.UploadPretreatment; import cn.xuyanwu.spring.file.storage.exception.FileStorageRuntimeException; @@ -9,7 +10,6 @@ import com.google.cloud.storage.*; import lombok.Getter; import lombok.Setter; -import org.springframework.core.io.Resource; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -30,10 +30,9 @@ public class GoogleCloudStorage implements FileStorage { private String projectId; private String bucketName; /** - * 配置文件路径,支持 classpath, file, http 等 - * 参考 Resource + * 证书路径,兼容Spring的ClassPath路径、文件路径、HTTP路径等 */ - private Resource credentialsLocation; + private String credentialsPath; /* 基础路径 */ private String basePath; /* 存储平台 */ @@ -49,10 +48,10 @@ public class GoogleCloudStorage implements FileStorage { public Storage getClient() { if (client == null) { ServiceAccountCredentials credentialsFromStream; - try { - credentialsFromStream = ServiceAccountCredentials.fromStream(credentialsLocation.getInputStream()); + try (InputStream in = URLUtil.url(credentialsPath).openStream()) { + credentialsFromStream = ServiceAccountCredentials.fromStream(in); } catch (IOException e) { - throw new FileStorageRuntimeException("Google Cloud Platform 授权 key 文件获取失败!credentialsLocation:" + credentialsLocation); + throw new FileStorageRuntimeException("Google Cloud Platform 授权 key 文件获取失败!credentialsPath:" + credentialsPath); } List scopes = Collections.singletonList("https://www.googleapis.com/auth/cloud-platform"); ServiceAccountCredentials credentials = credentialsFromStream.toBuilder().setScopes(scopes).build(); From 58149a84aaee036559eccdd487936e9f0788a81b Mon Sep 17 00:00:00 2001 From: xuyanwu <1171736840@qq.com> Date: Wed, 9 Nov 2022 16:13:28 +0800 Subject: [PATCH 4/9] =?UTF-8?q?update:=E8=B0=B7=E6=AD=8C=E4=BA=91=E5=AD=98?= =?UTF-8?q?=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" | 4 ++++ 1 file changed, 4 insertions(+) diff --git "a/docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" "b/docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" index b49c1378..5a9aea71 100644 --- "a/docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" +++ "b/docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" @@ -1,5 +1,9 @@ # 更新记录 +## 0.7.0 +2022-09-05 +- 增加对 谷歌云存储 的支持,由 [kytrun](https://github.com/1171736840/spring-file-storage/pull/42) 提供,非常感谢 + ## 0.6.1 2022-09-05 - 优化 ContentType 的识别方式 From 4258f8e1cbb548b373d43aae5be4280cb52b6f5f Mon Sep 17 00:00:00 2001 From: xuyanwu <1171736840@qq.com> Date: Wed, 9 Nov 2022 16:16:06 +0800 Subject: [PATCH 5/9] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=20WebDAV=20=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=E6=9C=89=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" | 1 + .../spring/file/storage/FileStorageAutoConfiguration.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git "a/docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" "b/docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" index 5a9aea71..89087977 100644 --- "a/docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" +++ "b/docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" @@ -3,6 +3,7 @@ ## 0.7.0 2022-09-05 - 增加对 谷歌云存储 的支持,由 [kytrun](https://github.com/1171736840/spring-file-storage/pull/42) 提供,非常感谢 +- 修复 WebDAV 提示有误 ## 0.6.1 2022-09-05 diff --git a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageAutoConfiguration.java b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageAutoConfiguration.java index c71439b8..11b3d41b 100644 --- a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageAutoConfiguration.java +++ b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageAutoConfiguration.java @@ -409,7 +409,7 @@ public void initDetect() { if (CollUtil.isNotEmpty(properties.getFtp()) && (doesNotExistClass("com.jcraft.jsch.ChannelSftp") || doesNotExistClass("cn.hutool.extra.ftp.Ftp"))) { log.warn(template," SFTP "); } - if (CollUtil.isNotEmpty(properties.getAwsS3()) && doesNotExistClass("com.github.sardine.Sardine")) { + if (CollUtil.isNotEmpty(properties.getWebDav()) && doesNotExistClass("com.github.sardine.Sardine")) { log.warn(template," WebDAV "); } if (CollUtil.isNotEmpty(properties.getGoogleCloud()) && doesNotExistClass("com.google.cloud.storage.Storage")) { From a9e79ec9f4c7e79243d85fb44a0249d0d6931254 Mon Sep 17 00:00:00 2001 From: xuyanwu <1171736840@qq.com> Date: Wed, 9 Nov 2022 16:45:36 +0800 Subject: [PATCH 6/9] add:Tika --- ...64\346\226\260\350\256\260\345\275\225.md" | 1 + spring-file-storage/pom.xml | 7 ++++++ .../storage/FileStorageAutoConfiguration.java | 15 +++++++++++- .../file/storage/FileStorageService.java | 23 ++++++++++++------- .../file/storage/tika/DefaultTikaFactory.java | 18 +++++++++++++++ .../spring/file/storage/tika/TikaFactory.java | 12 ++++++++++ 6 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/tika/DefaultTikaFactory.java create mode 100644 spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/tika/TikaFactory.java diff --git "a/docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" "b/docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" index 89087977..d401bccc 100644 --- "a/docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" +++ "b/docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" @@ -4,6 +4,7 @@ 2022-09-05 - 增加对 谷歌云存储 的支持,由 [kytrun](https://github.com/1171736840/spring-file-storage/pull/42) 提供,非常感谢 - 修复 WebDAV 提示有误 +- 使用 Tika 识别 ContentType ## 0.6.1 2022-09-05 diff --git a/spring-file-storage/pom.xml b/spring-file-storage/pom.xml index 34e7856e..20300f68 100644 --- a/spring-file-storage/pom.xml +++ b/spring-file-storage/pom.xml @@ -13,6 +13,13 @@ + + + org.apache.tika + tika-core + 2.4.1 + + com.github.lookfirst diff --git a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageAutoConfiguration.java b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageAutoConfiguration.java index 11b3d41b..009ac107 100644 --- a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageAutoConfiguration.java +++ b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageAutoConfiguration.java @@ -5,6 +5,8 @@ import cn.xuyanwu.spring.file.storage.platform.*; import cn.xuyanwu.spring.file.storage.recorder.DefaultFileRecorder; import cn.xuyanwu.spring.file.storage.recorder.FileRecorder; +import cn.xuyanwu.spring.file.storage.tika.DefaultTikaFactory; +import cn.xuyanwu.spring.file.storage.tika.TikaFactory; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -351,13 +353,23 @@ public FileRecorder fileRecorder() { return new DefaultFileRecorder(); } + /** + * Tika 工厂类型,用于识别上传的文件的 MINE + */ + @Bean + @ConditionalOnMissingBean(TikaFactory.class) + public TikaFactory tikaFactory() { + return new DefaultTikaFactory(); + } + /** * 文件存储服务 */ @Bean public FileStorageService fileStorageService(FileRecorder fileRecorder, List> fileStorageLists, - List aspectList) { + List aspectList, + TikaFactory tikaFactory) { this.initDetect(); FileStorageService service = new FileStorageService(); service.setFileStorageList(new CopyOnWriteArrayList<>()); @@ -365,6 +377,7 @@ public FileStorageService fileStorageService(FileRecorder fileRecorder, service.setFileRecorder(fileRecorder); service.setProperties(properties); service.setAspectList(new CopyOnWriteArrayList<>(aspectList)); + service.setTikaFactory(tikaFactory); return service; } diff --git a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageService.java b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageService.java index 492b74b5..6078aed0 100644 --- a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageService.java +++ b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageService.java @@ -1,5 +1,6 @@ package cn.xuyanwu.spring.file.storage; +import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.file.FileNameUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ReUtil; @@ -12,6 +13,7 @@ import cn.xuyanwu.spring.file.storage.exception.FileStorageRuntimeException; import cn.xuyanwu.spring.file.storage.platform.FileStorage; import cn.xuyanwu.spring.file.storage.recorder.FileRecorder; +import cn.xuyanwu.spring.file.storage.tika.TikaFactory; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -43,6 +45,7 @@ public class FileStorageService implements DisposableBean { private CopyOnWriteArrayList fileStorageList; private FileStorageProperties properties; private CopyOnWriteArrayList aspectList; + private TikaFactory tikaFactory; /** @@ -101,8 +104,7 @@ public FileInfo upload(UploadPretreatment pre) { } else if (pre.getFileWrapper().getContentType() != null) { fileInfo.setContentType(pre.getFileWrapper().getContentType()); } else { - String contentType = URLConnection.guessContentTypeFromName(fileInfo.getFilename()); - fileInfo.setContentType(contentType != null ? contentType : "application/octet-stream"); + fileInfo.setContentType(tikaFactory.getTika().detect(fileInfo.getFilename())); } byte[] thumbnailBytes = pre.getThumbnailBytes(); @@ -113,8 +115,7 @@ public FileInfo upload(UploadPretreatment pre) { } else { fileInfo.setThFilename(fileInfo.getFilename() + pre.getThumbnailSuffix()); } - String contentType = URLConnection.guessContentTypeFromName(fileInfo.getThFilename()); - fileInfo.setThContentType(contentType != null ? contentType : "application/octet-stream"); + fileInfo.setThContentType(tikaFactory.getTika().detect(thumbnailBytes,fileInfo.getThFilename())); } FileStorage fileStorage = getFileStorage(pre.getPlatform()); @@ -249,7 +250,8 @@ public UploadPretreatment of(MultipartFile file) { */ public UploadPretreatment of(byte[] bytes) { UploadPretreatment pre = of(); - pre.setFileWrapper(new MultipartFileWrapper(new MockMultipartFile("",bytes))); + String contentType = tikaFactory.getTika().detect(bytes); + pre.setFileWrapper(new MultipartFileWrapper(new MockMultipartFile("","",contentType,bytes))); return pre; } @@ -258,8 +260,10 @@ public UploadPretreatment of(byte[] bytes) { */ public UploadPretreatment of(InputStream in) { try { + byte[] bytes = IoUtil.readBytes(in); + String contentType = tikaFactory.getTika().detect(bytes); UploadPretreatment pre = of(); - pre.setFileWrapper(new MultipartFileWrapper(new MockMultipartFile("",in))); + pre.setFileWrapper(new MultipartFileWrapper(new MockMultipartFile("","",contentType,bytes))); return pre; } catch (Exception e) { throw new FileStorageRuntimeException("根据 InputStream 创建上传预处理器失败!",e); @@ -272,7 +276,8 @@ public UploadPretreatment of(InputStream in) { public UploadPretreatment of(File file) { try { UploadPretreatment pre = of(); - pre.setFileWrapper(new MultipartFileWrapper(new MockMultipartFile(file.getName(),file.getName(),URLConnection.guessContentTypeFromName(file.getName()),Files.newInputStream(file.toPath())))); + String contentType = tikaFactory.getTika().detect(file); + pre.setFileWrapper(new MultipartFileWrapper(new MockMultipartFile(file.getName(),file.getName(),contentType,Files.newInputStream(file.toPath())))); return pre; } catch (Exception e) { throw new FileStorageRuntimeException("根据 File 创建上传预处理器失败!",e); @@ -305,7 +310,9 @@ public UploadPretreatment of(URL url) { } } - pre.setFileWrapper(new MultipartFileWrapper(new MockMultipartFile(url.toString(),name,conn.getContentType(),conn.getInputStream()))); + byte[] bytes = IoUtil.readBytes(conn.getInputStream()); + String contentType = tikaFactory.getTika().detect(bytes,name); + pre.setFileWrapper(new MultipartFileWrapper(new MockMultipartFile(url.toString(),name,contentType,bytes))); return pre; } catch (Exception e) { throw new FileStorageRuntimeException("根据 URL 创建上传预处理器失败!",e); diff --git a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/tika/DefaultTikaFactory.java b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/tika/DefaultTikaFactory.java new file mode 100644 index 00000000..4bdb0879 --- /dev/null +++ b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/tika/DefaultTikaFactory.java @@ -0,0 +1,18 @@ +package cn.xuyanwu.spring.file.storage.tika; + +import org.apache.tika.Tika; + +/** + * 默认的 Tika 工厂类 + */ +public class DefaultTikaFactory implements TikaFactory { + private Tika tika; + + @Override + public Tika getTika() { + if (tika == null) { + tika = new Tika(); + } + return tika; + } +} diff --git a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/tika/TikaFactory.java b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/tika/TikaFactory.java new file mode 100644 index 00000000..cedd6b5c --- /dev/null +++ b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/tika/TikaFactory.java @@ -0,0 +1,12 @@ +package cn.xuyanwu.spring.file.storage.tika; + +import org.apache.tika.Tika; + +/** + * Tika 工厂类接口 + */ +public interface TikaFactory { + + Tika getTika(); + +} From dda559d703f567f67031cb50c1747116c48d763d Mon Sep 17 00:00:00 2001 From: xuyanwu <1171736840@qq.com> Date: Fri, 11 Nov 2022 16:46:05 +0800 Subject: [PATCH 7/9] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/xuyanwu/spring/file/storage/FileStorageService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageService.java b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageService.java index 6078aed0..8358a43b 100644 --- a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageService.java +++ b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/FileStorageService.java @@ -346,7 +346,7 @@ public void destroy() { for (FileStorage fileStorage : fileStorageList) { try { fileStorage.close(); - log.error("销毁存储平台 {} 成功",fileStorage.getPlatform()); + log.info("销毁存储平台 {} 成功",fileStorage.getPlatform()); } catch (Exception e) { log.error("销毁存储平台 {} 失败,{}",fileStorage.getPlatform(),e.getMessage(),e); } From aa0ceb7e16d85059ceccc9d445e60702b5704a2d Mon Sep 17 00:00:00 2001 From: xuyanwu <1171736840@qq.com> Date: Mon, 14 Nov 2022 10:31:01 +0800 Subject: [PATCH 8/9] Release:0.7.0 --- docs/_navbar.md | 3 ++- "docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" | 2 +- pom.xml | 2 +- spring-file-storage-test/pom.xml | 4 ++-- spring-file-storage/pom.xml | 2 +- .../spring/file/storage/platform/GoogleCloudStorage.java | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/_navbar.md b/docs/_navbar.md index 2499dd8a..e716ae58 100644 --- a/docs/_navbar.md +++ b/docs/_navbar.md @@ -1,5 +1,6 @@ -* 文档版本 0.6.1 +* 文档版本 0.7.0 + * [0.7.0](https://spring-file-storage.xuyanwu.cn/0.7.0/) * [0.6.1](https://spring-file-storage.xuyanwu.cn/0.6.1/) * [0.6.0](https://spring-file-storage.xuyanwu.cn/0.6.0/) * [0.5.0](https://spring-file-storage.xuyanwu.cn/0.5.0/) diff --git "a/docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" "b/docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" index d401bccc..4d198667 100644 --- "a/docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" +++ "b/docs/\346\233\264\346\226\260\350\256\260\345\275\225.md" @@ -1,7 +1,7 @@ # 更新记录 ## 0.7.0 -2022-09-05 +2022-11-14 - 增加对 谷歌云存储 的支持,由 [kytrun](https://github.com/1171736840/spring-file-storage/pull/42) 提供,非常感谢 - 修复 WebDAV 提示有误 - 使用 Tika 识别 ContentType diff --git a/pom.xml b/pom.xml index 467b45b2..b351c96b 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ cn.xuyanwu spring-file-storage-parent pom - 0.6.1 + 0.7.0 spring-file-storage-parent A File Storage Service diff --git a/spring-file-storage-test/pom.xml b/spring-file-storage-test/pom.xml index 1bb1d91b..fc112347 100644 --- a/spring-file-storage-test/pom.xml +++ b/spring-file-storage-test/pom.xml @@ -12,7 +12,7 @@ cn.xuyanwu spring-file-storage-test - 0.6.1 + 0.7.0 spring-file-storage-test spring-file-storage 的测试和演示模块 @@ -130,7 +130,7 @@ cn.xuyanwu spring-file-storage - 0.6.1 + 0.7.0 diff --git a/spring-file-storage/pom.xml b/spring-file-storage/pom.xml index 20300f68..c0589e0f 100644 --- a/spring-file-storage/pom.xml +++ b/spring-file-storage/pom.xml @@ -5,7 +5,7 @@ spring-file-storage-parent cn.xuyanwu - 0.6.1 + 0.7.0 4.0.0 diff --git a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/platform/GoogleCloudStorage.java b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/platform/GoogleCloudStorage.java index d79a758c..385999a7 100644 --- a/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/platform/GoogleCloudStorage.java +++ b/spring-file-storage/src/main/java/cn/xuyanwu/spring/file/storage/platform/GoogleCloudStorage.java @@ -22,7 +22,7 @@ /** * @author Kytrun * @version 1.0 - * @date 2022/11/4 9:56 + * {@code @date} 2022/11/4 9:56 */ @Getter @Setter From 94ddf54ce279713d93c677015d7567b9973b8efc Mon Sep 17 00:00:00 2001 From: xuyanwu <1171736840@qq.com> Date: Mon, 14 Nov 2022 10:44:20 +0800 Subject: [PATCH 9/9] =?UTF-8?q?update:=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- docs/README.md | 2 +- .../\345\255\230\345\202\250\345\271\263\345\217\260.md" | 8 ++++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ceafd7a3..20afed53 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ ### 简介 在 SpringBoot 中通过简单的方式将文件存储到 -本地、FTP、SFTP、WebDAV、阿里云OSS、华为云OBS、七牛云Kodo、腾讯云COS、百度云 BOS、又拍云USS、MinIO、 +本地、FTP、SFTP、WebDAV、谷歌云存储、阿里云OSS、华为云OBS、七牛云Kodo、腾讯云COS、百度云 BOS、又拍云USS、MinIO、 AWS S3、金山云 KS3、美团云 MSS、京东云 OSS、天翼云 OOS、移动云 EOS、沃云 OSS、 网易数帆 NOS、Ucloud US3、青云 QingStor、平安云 OBS、首云 OSS、IBM COS、其它兼容 S3 协议的平台 diff --git a/docs/README.md b/docs/README.md index a044f1bc..d5e59651 100644 --- a/docs/README.md +++ b/docs/README.md @@ -24,7 +24,7 @@ # 简介 在 SpringBoot 中通过简单的方式将文件存储到 -本地、FTP、SFTP、WebDAV、阿里云OSS、华为云OBS、七牛云Kodo、腾讯云COS、百度云 BOS、又拍云USS、MinIO、 +本地、FTP、SFTP、WebDAV、谷歌云存储、阿里云OSS、华为云OBS、七牛云Kodo、腾讯云COS、百度云 BOS、又拍云USS、MinIO、 AWS S3、金山云 KS3、美团云 MSS、京东云 OSS、天翼云 OOS、移动云 EOS、沃云 OSS、 网易数帆 NOS、Ucloud US3、青云 QingStor、平安云 OBS、首云 OSS、IBM COS、其它兼容 S3 协议的平台 diff --git "a/docs/\345\255\230\345\202\250\345\271\263\345\217\260.md" "b/docs/\345\255\230\345\202\250\345\271\263\345\217\260.md" index 8235e3c8..b9999605 100644 --- "a/docs/\345\255\230\345\202\250\345\271\263\345\217\260.md" +++ "b/docs/\345\255\230\345\202\250\345\271\263\345\217\260.md" @@ -198,3 +198,11 @@ FileStorage myLocal = fileStorageService.getFileStorage("my-local-1"); list.remove(myLocal); myLocal.close();//释放资源 ``` + +## 获取对应存储平台 + +```java +AliyunOssFileStorage storage = (AliyunOssFileStorage) fileStorageService.getFileStorage("aliyun-oss-1"); +OSS client = storage.getClient(); +//获取到对应SDK的原生客户端对象,可以进行更多高级操作 +```