1

我有一个使用骆驼从对象存储(谷歌云平台)获取数据的弹簧启动应用程序。

这是我在eclipse中的代码:

package footballRestAPIs;

import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;

import core.ErrorProcessor;


@Component
public class ListObjFromGCP extends RouteBuilder{
    
    
     @Override
        public void configure() throws Exception {
            
       
            onException(Exception.class).handled(true)
            .process(new ErrorProcessor());
            

            rest("/").produces("application.json") 
            .get("selectPhoto")
            
            .to("direct:selectPhoto");

        from("direct:selectPhoto")
        
          .to("google-storage://sagessapp_test?operation=listObjects")
        
          .log("${body}");
            
            
         
        }

}

这是 application.properties 文件,其中服务帐户密钥的路径是:

spring.cloud.gcp.credentials.location=/Users/User/Downloads/gcp-credentials.json

当我运行 spring boot 应用程序时,出现以下错误:

Caused by: com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
GET https://storage.googleapis.com/storage/v1/b/sagessapp_test?projection=full
{
  "code" : 401,
  "errors" : [ {
    "domain" : "global",
    "location" : "Authorization",
    "locationType" : "header",
    "message" : "Anonymous caller does not have storage.buckets.get access to the Google Cloud Storage bucket.",
    "reason" : "required"
  } ],
  "message" : "Anonymous caller does not have storage.buckets.get access to the Google Cloud Storage bucket."
}

是否有可能有另一种方法来提供服务帐户密钥的路径,或者存在其他问题。谢谢!

4

1 回答 1

1

TL;DR创建一个Credentials实例:

Credentials credentials = GoogleCredentials.fromStream(new FileInputStream("path/to/file")); 

谷歌云存储设置

文档中,除了您已经在使用的方法之外,还有一些方法可以加载凭据*: *请注意,如果未通过属性文件指定凭据,则将使用这些方法

环境变量

您可以设置环境变量GOOGLE_APPLICATION_CREDENTIALS并使用默认实例:

对于 Linux 或 Mac:

export GOOGLE_APPLICATION_CREDENTIALS="/path/to/file"

对于 Windows:

set GOOGLE_APPLICATION_CREDENTIALS="C:\path\to\file"

这是加载凭据的最简单方法。

云 SDK

另一种方法是使用 Google Cloud SDK 提供凭据。步骤如下:

  1. 首先安装 Cloud SDK
  2. 然后初始化 Cloud SDK。在第 4 步,选择您正在处理的项目。
  3. 然后你可以运行gcloud auth application-default login 命令。正如在这个答案中发布的:

    这会通过 Web 流获取您的凭据并将它们存储在“应用程序默认凭据的知名位置”。现在,您运行的任何代码/SDK 都将能够自动找到凭据。当您想要在本地测试通常在服务器上运行并使用服务器端凭据文件的代码时,这是一个很好的替代方案。

连接到 存储

在我们可以使用谷歌云存储之前,我们必须创建一个服务对象。如果我们已经设置了GOOGLE_APPLICATION_CREDENTIALS环境变量,我们可以使用默认实例:

Storage storage = StorageOptions.getDefaultInstance().getService();

如果我们不想使用环境变量,我们必须创建一个Credentials实例并将其Storage与项目名称一起传递给:

Credentials credentials = GoogleCredentials.fromStream(new FileInputStream("path/to/file"));
// The ID of your GCP project
// String projectId = "your-project-id";
Storage storage = StorageOptions.newBuilder().setCredentials(credentials).setProjectId("your-project-id").build().getService();

创建存储桶

桶是存放对象的容器。它们可用于组织和控制数据访问。

创建存储桶需要BucketInfo

Bucket bucket = storage.create(BucketInfo.of("sample-bucket"));

对于这个简单的示例,我们传递一个存储桶名称并接受默认属性。存储桶名称必须是全局唯一的,并且还必须遵循一些要求。例如,如果我们选择一个已经使用的名称,create()就会失败。

读取数据

Blob 在创建时被分配一个 BlobId

检索 Blob 的最简单方法是使用 BlobId

Blob blob = storage.get(blobId);
String value = new String(blob.getContent());

我们将 id 传递给 Storage 并获取 Blob in 返回,然后 getContent() 返回字节。

如果我们没有 BlobId,我们可以按名称搜索 Bucket:

// The ID of your GCS bucket
// String bucketName = "your-unique-bucket-name";
Page<Blob> blobs = storage.list(bucketName);
for (Blob blob: blobs.getValues()) {
    if (name.equals(blob.getName())) {
        return new String(blob.getContent());
    }
}

列出对象

这是列出 Cloud Storage 存储分区中所有对象的函数的代码示例。

import com.google.api.gax.paging.Page;
import com.google.cloud.storage.Blob;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;

public class ListObjects {
  public static void listObjects(String projectId, String bucketName) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of your GCS bucket
    // String bucketName = "your-unique-bucket-name";

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
    Page<Blob> blobs = storage.list(bucketName);

    for (Blob blob : blobs.iterateAll()) {
      System.out.println(blob.getName());
    }
  }
}

也可以看看:

于 2021-11-18T23:35:10.827 回答