首页 > 解决方案 > 恼人的 Google API 客户端 (Java) 问题

问题描述

所以我所做的需要我用 google sheet api 打一个文档,抓取一张表,从中提取数据,然后生成另一张表。因此,最初我使用服务帐户遵循了一个示例,如下所示:

@Bean(name = "google-creds")
@DependsOn(value = {"google-http-transport", "google-data-store", "json-factory"})
public GoogleCredential authorize(HttpTransport transport, JsonFactory factory) throws Exception {
    // Load client secrets.
    InputStream in = new FileInputStream(new File("config/oauth.json"));
    return GoogleCredential.fromStream(in, transport, factory).createScoped(SCOPES);
}

我的 oauth.json 文件正在使用 API 控制台凭据选项卡中生成的 json 文件。我按照指示生成了一个服务帐户……我有点怀疑。

我能够从我想要的文档中提取数据,并且能够创建另一个文档。但是据我所知,无法查看使用服务帐户创建的文档。哪个...我的意思是这使它完全无用。如果有一种方法可以让我从主帐户中查看这些文档,那么创建服务帐户就太棒了。然而,一些谷歌的答案似乎暗示这是不可能的。

所以好吧,我决定如何尝试使用主账户中的客户 ID。我下载了提供的 json 文件,但它出错并显示未知字段“类型”。所以..我猜它使用来自 gson 的 RuntimeTypeAdapter 或其他东西进行序列化。所以它与主账户的凭证格式完全不兼容。

所以接下来我试着这样做

    @Bean(name = "google-creds")
    @DependsOn(value = {"google-http-transport", "google-data-store"})
    public Credential authorize(HttpTransport transport) throws Exception {
        // Load client secrets.
        InputStream in = new FileInputStream(new File("config/oauthnew.json"));
        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JacksonFactory.getDefaultInstance(), new InputStreamReader(in));
        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(transport, factory, clientSecrets, SCOPES)
                .setDataStoreFactory(new MemoryDataStoreFactory()).build();
        Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
        return credential;
    }

所以我并没有真正读到这个,结果它创建了一个本地码头服务器......一些莫名其妙的原因。它还要求我去访问一个 URL,然后它会抱怨重定向。我不想进行任何类型的重定向,或者......除了解析和制作该死的电子表格之外的任何东西。如果需要已经对帐户进行身份验证,那么访问 URL 也已经是一个交易破坏者。这需要每 10 分钟左右以编程方式运行一次。

此外,当我使用上面的示例时,我找不到任何地方可以以任何形式或形式配置共享或权限。Google 通常有很好的 API,但这是我在近十年的 Java 开发中使用过的最烦人的 API。我只需要能够 A) 解析工作表 AB) 必要时创建工作表 B 和 C) 能够查看工作表 B

有人能指点我一个不会让我对着显示器尖叫的方向吗?

标签: javagoogle-app-enginegoogle-sheetsgoogle-sheets-apigoogle-api-java-client

解决方案


服务帐户用于以编程方式访问用户日期,它没有自己的文档/驱动器。您需要在创建 GoogleCredential 时提供用户的电子邮件地址。服务帐户将访问所需的用户文档(假设它启用了域范围的委派)。目前来自Stream的GoogleCredentials存在一个未解决的问题,请查看(解决它)https://github.com/google/google-api-java-client/issues/1007#issuecomment-318493967

如果用户帐户是 gsuite 帐户,您可以通过 Google 管理控制台https://admin.google.com/为服务帐户授予范围权限

有关域范围委派和授予访问权限的详细信息,请查看https://developers.google.com/admin-sdk/directory/v1/guides/delegation

为了查看由具有域范围委派的服务帐户创建的文档,您必须使用用户帐户访问它。

现在,如果您可以通过 Google 管理控制台授予访问权限的帐户,您将不得不使用流程(您的第二种方法)。不幸的是,这将要求您必须通过提供的 url 授予对文档的权限。一旦授予权限,您就可以存储令牌,这样就无需重复此过程。


推荐阅读