我有一个spring-boot应用程序,它使用camel从对象存储(谷歌云平台(获取数据。
这是我在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."
}
是否有其他方法可以提供服务帐户密钥的路径,或者存在其他问题。非常感谢。
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:pathtofile"
这是加载凭据的最简单方法。
云SDK
另一种方法是使用Google Cloud SDK提供凭据。步骤如下:
- 首先安装云SDK
- 然后初始化云SDK。在步骤4中,选择您正在处理的项目
- 然后可以运行
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();
创建存储桶
水桶是用来装东西的容器。它们可用于组织和控制数据访问。
创建bucket需要BucketInfo
:
Bucket bucket = storage.create(BucketInfo.of("sample-bucket"));
对于这个简单的示例,我们传递一个bucket名称并接受默认属性。Bucket名称必须是全局唯一的,并且必须符合一些要求。例如,如果我们选择一个已经使用的名称,create()
将失败。
正在读取数据
Blob在创建时被指定一个Blob ID。
检索Blob的最简单方法是使用BlobId
:
Blob blob = storage.get(blobId);
String value = new String(blob.getContent());
我们将id传递给Storage
并得到Blob
作为返回,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());
}
}
列出对象
这是一个函数的代码示例,该函数列出了云存储桶中的所有对象。
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());
}
}
}
另请参阅:
- https://github.com/googleapis/google-cloud-java#authentication