使用 Spring Resource 抽象访问 Cloud Storage 中的文件

1. 概览

Spring Framework 提供了 ResourceLoader 抽象,可让您轻松地从文件系统、类路径或网页等各种来源读取和写入文件。您只需使用众所周知的协议前缀来指定资源的 URI。例如,如需访问本地文件系统上的文件,需指定 URI,如 file:/data/config.yaml

您将编写一个 Spring Boot 应用,该应用将使用 Spring Resource 抽象和 gs: 协议前缀来访问存储在 Cloud Storage 中的文件。

为此,您可以使用 Cloud Shell 和 Cloud SDK gcloud 命令行工具。

学习内容

  • 如何使用 Cloud Storage Spring Boot 入门版
  • 如何使用 Spring 访问 Cloud Storage 中的文件
  • 如何使用 Spring 的 ResourceWritableResource 抽象

所需的条件

  • Google Cloud 项目
  • 浏览器,例如 Google Chrome
  • 熟悉标准的 Linux 文本编辑器,例如 Vim、Emacs 和 GNU Nano

您将如何使用此 Codelab?

仅阅读 阅读并完成练习

您如何评价自己在构建 HTML 和 CSS Web 应用方面的经验水平?

新手水平 中等水平 熟练水平

您如何评价自己在使用 Google Cloud 服务方面的经验水平?

<ph type="x-smartling-placeholder"></ph> 新手 中级 熟练

2. 设置和要求

自定进度的环境设置

  1. 登录 Cloud 控制台,然后创建一个新项目或重复使用现有项目。 (如果您还没有 Gmail 或 G Suite 账号,则必须创建一个。)

dMbN6g9RawQj_VXCSYpdYncY-DbaRzr2GbnwoV7jFf1u3avxJtmGPmKpMYgiaMH-qu80a_NJ9p2IIXFppYk8x3wyymZXavjglNLJJhuXieCem56H30hwXtd8PvXGpXJO9gEUDu3cZw

ci9Oe6PgnbNuSYlMyvbXF1JdQyiHoEgnhl4PlV_MFagm2ppzhueRkqX4eLjJllZco_2zCp0V0bpTupUSKji9KkQyWqj11pqit1K1faS1V6aFxLGQdkuzGp4rsQTan7F01iePL5DtqQ

8-tA_Lheyo8SscAVKrGii2coplQp2_D1Iosb2ViABY0UUO1A8cimXUu6Wf1R9zJIRExL5OB2j946aIiFtyKTzxDcNnuznmR45vZ2HMoK3o67jxuoUJCAnqvEX6NgPGFjCVNgASc-lg

请记住项目 ID,它在所有 Google Cloud 项目中都是唯一的名称(上述名称已被占用,您无法使用,抱歉!)。它稍后将在此 Codelab 中被称为 PROJECT_ID

  1. 接下来,您需要在 Cloud 控制台中启用结算功能,才能使用 Google Cloud 资源。

运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。请务必按照“清理”部分部分,其中会指导您如何关停资源,以免产生超出本教程范围的结算费用。Google Cloud 的新用户符合参与 $300 USD 免费试用计划的条件。

Cloud Shell

您将使用 Cloud Shell,这是一个在 Google Cloud 中运行的命令行环境。

激活 Cloud Shell

  1. 在 Cloud Console 中,点击激活 Cloud ShellH7JlbhKGHITmsxhQIcLwoe5HXZMhDlYue4K-SPszMxUxDjIeWfOHBfxDHYpmLQTzUmQ7Xx8o6OJUlANnQF0iBuUyfp1RzVad_4nCa0Zz5LtwBlUZFXFCWFrmrWZLqg1MkZz2LdgUDQ

zlNW0HehB_AFW1qZ4AyebSQUdWm95n7TbnOr7UVm3j9dFcg6oWApJRlC0jnU1Mvb-IQp-trP1Px8xKNwt6o3pP6fyih947sEhOFI4IRF0W7WZk6hFqZDUGXQQXrw21GuMm2ecHrbzQ

如果您以前从未启动过 Cloud Shell,将看到一个中间屏幕(在折叠下面),描述它是什么。如果是这种情况,请点击继续(您将永远不会再看到它)。一次性屏幕如下所示:

kEPbNAo_w5C_pi9QvhFwWwky1cX8hr_xEMGWySNIoMCdi-Djx9AQRqWn-__DmEpC7vKgUtl-feTcv-wBxJ8NwzzAp7mY65-fi2LJo4twUoewT1SUjd6Y3h81RG3rKIkqhoVlFR-G7w

预配和连接到 Cloud Shell 只需花几分钟时间。

pTv5mEKzWMWp5VBrg2eGcuRPv9dLInPToS-mohlrqDASyYGWnZ_SwE-MzOWHe76ZdCSmw0kgWogSJv27lrQE8pvA5OD6P1I47nz8vrAdK7yR1NseZKJvcxAZrPb8wRxoqyTpD-gbhA

这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 5GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证。只需使用一个浏览器或 Google Chromebook 即可完成本 Codelab 中的大部分(甚至全部)工作。

在连接到 Cloud Shell 后,您应该会看到自己已通过身份验证,并且相关项目已设置为您的项目 ID:

  1. 在 Cloud Shell 中运行以下命令以确认您已通过身份验证:
gcloud auth list

命令输出

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

命令输出

[core]
project = <PROJECT_ID>

如果不是上述结果,您可以使用以下命令进行设置:

gcloud config set project <PROJECT_ID>

命令输出

Updated property [core/project].

3. 在 Cloud Storage 中创建文件

启动 Cloud Shell 后,您可以开始创建文件,并将其传输到 Cloud Storage。

创建一个名为 my-file.txt 的文件:

$ echo "Hello World from GCS" > my-file.txt

然后,在 Cloud Storage 中创建新的唯一存储桶,并使用 gsutil 将文件传输到其中。

$ BUCKET=spring-bucket-$USER
$ gsutil makebucket gs://$BUCKET
$ gsutil copy my-file.txt gs://$BUCKET

前往 Cloud Storage 中的存储浏览器,并验证该存储分区和文件是否存在。

4. 初始化 Spring Boot 应用

使用命令行开始编写应用,以通过 Spring Initializr 生成一个新的 Spring Boot 应用:

$ curl https://start.spring.io/starter.tgz \
  -d type=maven-project \
  -d dependencies=web,cloud-gcp-storage -d baseDir=spring-gcs | tar -xzvf -

请注意,Initializr 会自动将 spring-boot-starter-webspring-cloud-gcp-starter-storage 添加到模板应用 pom.xml 的依赖项中。

切换到模板应用的目录:

$ cd spring-gcs

确保 JAVA_HOME 设置为正确的 JDK 版本:

$ export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64/

使用 Maven 构建并运行应用。

$ ./mvnw spring-boot:run

该应用将开始监听端口 8080。打开新的 Cloud Shell 标签页,然后运行 curl 来访问应用。

$ curl localhost:8080

您应该会收到 404 响应,因为应用尚未执行任何有用的操作。

返回运行应用的上一个 Cloud Shell 标签页,然后使用 Control+C(在 Macintosh 上为 Command+C)终止它。

5. 读取 Cloud Storage 中的文件

修改 Spring Boot 应用以访问 my-file.txt(之前存储在 Cloud Storage 中的文件)。您的目标只是通过 HTTP 返回文件的内容。

在以下说明中,您将使用 Vim 修改文件,但您也可以使用 Emacs、GNU Nano 或 Cloud Shell 中的内置代码编辑器:

cloud-editor.png

$ cd ~/spring-gcs

将 REST 控制器 GcsController 添加到应用中。

$ vi src/main/java/com/example/demo/GcsController.java

粘贴以下代码,并且不要忘了使用您之前创建的存储桶修复资源 URI。您可以通过运行 echo $BUCKET 命令检查存储桶。

src/main/java/com/example/demo/GcsController.java

package com.example.demo;

import java.io.IOException;
import java.nio.charset.Charset;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GcsController {

  @Value("gs://REPLACE_WITH_YOUR_BUCKET/my-file.txt")
  private Resource gcsFile;

  @GetMapping("/")
  public String readGcsFile() throws IOException {
    return StreamUtils.copyToString(
        gcsFile.getInputStream(),
        Charset.defaultCharset());
  }
}

使用 Maven 构建并运行应用:

$ ./mvnw spring-boot:run

该应用现在即开始监听端口 8080。打开新的 Cloud Shell 标签页,然后运行 curl 来访问应用。

$ curl localhost:8080

现在,您应该会看到从应用返回的文件的内容。转到运行该应用的上一个 Cloud Shell 标签页,然后使用 Control+C(在 Macintosh 上为 Command+C)终止它。

6. 写入 Cloud Storage 中的文件

您将读取 Cloud Storage 中文件的内容,并通过 Spring REST 控制器将其公开。现在,将新文件内容发布到同一 HTTP 端点,以更改该文件的内容。

您需要向 GcsController 添加另一个响应 HTTP POST 的方法,并将数据写入 Cloud Storage 中的文件。这次,将 Spring Resource 类型转换为 WritableResource

使用所需的其他导入内容更新 GcsController

src/main/java/com/example/demo/GcsController.java

import java.io.OutputStream;
import org.springframework.core.io.WritableResource;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PostMapping;

将新的端点方法添加到控制器。

src/main/java/com/example/demo/GcsController.java

@RestController
public class GcsController {

  @PostMapping("/")
  String writeGcs(@RequestBody String data) throws IOException {
    try (OutputStream os = ((WritableResource) gcsFile).getOutputStream()) {
      os.write(data.getBytes());
    }
    return "file was updated\n";
  }
  ...
}

使用 Maven 构建并运行应用:

$ ./mvnw spring-boot:run

该应用现在即开始监听端口 8080。打开新的 Cloud Shell 标签页,然后运行 curl 以将消息发布到应用。

$ curl -d 'new message' -H 'Content-Type: text/plain' localhost:8080

您应该会看到确认文件内容已更新的信息。 不过,请通过执行 GET 进行验证。

$ curl localhost:8080

您应该会看到从应用返回的文件更新后的内容。返回运行应用的上一个 Cloud Shell 标签页,然后使用 Control+C(在 Macintosh 上为 Command+C)终止它。

7. 恭喜!

您学习了如何使用 Spring Resource 抽象来轻松访问 Cloud Storage 中的文件。您编写了可以对 Cloud Storage 中的文件执行读写操作的 Spring Boot Web 应用。您还了解了适用于 Cloud Storage 的 Spring Boot 入门版(启用了该功能)。

了解详情

许可

此作品已获得 Creative Commons Attribution 2.0 通用许可授权。