首页 > 解决方案 > 有没有办法为单个 Java 项目包含多个 Google API 服务(例如 Sheets 和 Docs)?

问题描述

我第一次将 Google 的 API 服务用于个人 Java 项目,该项目涉及从 Google Sheet 读取数据并将与之相关的信息写入单独的 Google Doc。

对于此处此处列出的内容,我都使用了 Google 的快速入门指南。在遵循 Google 表格指南并使用我自己的文件对其进行测试时,我设法让一切正常运行。

但是,在尝试将我新生成的凭据(Google Doc)添加到已创建的 credentials.json 文件时,尝试为 Doc 设置 API 似乎会出现问题。我认为这是因为已经为我的表格文件创建了凭据,因此我不能简单地添加新创建的凭据。我还尝试通过创建一个名为 doccredentials.json 的新凭据文件来尝试同时使用两者,但在尝试gradle run再次执行以编译 Google Doc API 服务时遇到了这个问题:

Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "Insufficient Permission",
    "reason" : "insufficientPermissions"
  } ],
  "message" : "Request had insufficient authentication scopes.",
  "status" : "PERMISSION_DENIED"
}

我最好的猜测是正在使用工作表的凭据,但我不确定如何规避它。我还确保我的CREDENTIALS_FILE_PATH变量也设置到了正确的位置,所以我很确定它正在尝试从正确的文件中读取。

任何建议,将不胜感激。谢谢。

编辑:这是我的身份验证代码块中的内容。它最初只是为了验证 Sheet API 而设置的,但是,在仔细检查之后,它似乎很可能是由于不正确地设置了 Scopes。关于如何允许电子表格和文档的范围有什么建议吗?:

private static Credential authorize() throws IOException, GeneralSecurityException {
    InputStream in = InventoryManagerSheet.class.getResourceAsStream("/credentials.json");
    GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JacksonFactory.getDefaultInstance(), new InputStreamReader(in));

    List<String> scopes = Arrays.asList(SheetsScopes.SPREADSHEETS);

    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(GoogleNetHttpTransport.newTrustedTransport(), JacksonFactory.getDefaultInstance(),
    clientSecrets, scopes).setDataStoreFactory(new FileDataStoreFactory(new java.io.File("tokens"))).setAccessType("offline").build();

    Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");

    return credential;
}

标签: javagradlegoogle-apigoogle-oauthgoogle-api-java-client

解决方案


与您的错误消息相关的答案

我在没有看到您的代码的情况下编写此代码,一旦您拥有,我将对其进行编辑,但这可能会有所帮助。

"请求的身份验证范围不足。",

表示当前进行身份验证的用户没有授予您足够的权限来执行您尝试执行的操作。

您提到的教程要求用户提供以下范围

private static final List<String> SCOPES = Collections.singletonList(DocsScopes.DOCUMENTS_READONLY);

你提到你想写信给谷歌文档。如您所见,此范围仅允许对文档进行 READONLY 访问。你可能应该使用,但这只是一个猜测,你将不得不检查我在 java 客户端库中的名称是否不同。

private static final List<String> SCOPES = Collections.singletonList(DocsScopes.DOCUMENTS);

也可能是的,您可以混合使用范围。

private static final List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE);

完成此操作后,您需要转到 CREDENTIALS_FILE_PATH 并删除为“用户”创建的凭据文件,这将迫使您的代码再次请求用户授权并请求对您的文件的写访问权。

与您的实际问题相关的答案

现在回到您的问题,这与您的错误消息无关。您可以从诈骗应用程序访问两个不同的 API,但您需要为每个 API 创建一个服务

以下服务可让您访问 Google docs api

Docs service = new Docs.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
                .setApplicationName(APPLICATION_NAME)
                .build();

以下服务将使您的代码访问 Google drive api

Drive service = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
                .setApplicationName(APPLICATION_NAME)
                .build();

只是给他们不同的名字。请记住为每个 api 添加所需的范围,您可以混合它们。


推荐阅读