【问题标题】:How do you access a Google Sheet with a service account from Java?如何使用 Java 服务帐户访问 Google 表格?
【发布时间】:2020-09-30 10:33:06
【问题描述】:

我正在尝试从服务帐户访问 Google 表格(服务帐户有权访问表格)。但我有一个问题,包括official docs 在内的所有文档都指向使用GoogleCredential,自1.7 起已弃用。弃用表示您应该使用库google-auth-library,这就是我正在做的事情:

val googleCredentials = ServiceAccountCredentials
      .fromStream(new FileInputStream(CREDENTIALS_FILE_PATH))
      .createScoped(SCOPES)
googleCredentials.refresh()

但是变量的类型是GoogleCredentials,而函数Sheets.Builder 不接受这是一个有效的HttpRequestInitializer。因此,我不得不通过以下方式破解已弃用的类:

val token = googleCredentials.getAccessToken.getTokenValue
val credential = new GoogleCredential().setAccessToken(token)

通过这种解决方法,我可以访问 Google 表格,但我确信有一种正确的方法可以在不使用已弃用的库的情况下做到这一点。

有谁知道正确的做法是什么?

这里留下完整的 sn-p 作为参考。

package drivers
import java.io.FileInputStream
import java.util.Collections

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport
import com.google.api.client.json.jackson2.JacksonFactory
import com.google.api.services.sheets.v4.{Sheets, SheetsScopes}
import com.google.auth.oauth2.ServiceAccountCredentials
import com.typesafe.config.ConfigFactory

object TestDriver {

  def main(args: Array[String]): Unit = {
    val config = ConfigFactory.load()
    val spreadsheetId = config.getString("spreadsheetId")
    val CREDENTIALS_FILE_PATH = config.getString("google_application_credentials")

    val SCOPES = Collections.singletonList(SheetsScopes.SPREADSHEETS_READONLY)
    val JSON_FACTORY = JacksonFactory.getDefaultInstance
    val APPLICATION_NAME = "my-app"

    val googleCredentials = ServiceAccountCredentials
      .fromStream(new FileInputStream(CREDENTIALS_FILE_PATH))
      .createScoped(SCOPES)
    googleCredentials.refresh()

    val token = googleCredentials.getAccessToken.getTokenValue
    val credential = new GoogleCredential().setAccessToken(token)
    val httpTransport = GoogleNetHttpTransport.newTrustedTransport
    val service = new Sheets.Builder(httpTransport, JSON_FACTORY, credential)
      .setApplicationName(APPLICATION_NAME)
      .build()
    val range = "Sheet1!A1:D1"
    val response = service.spreadsheets().values().get(spreadsheetId, range).execute()
    val values = response.getValues
    values.forEach(println)
  }

【问题讨论】:

    标签: java google-sheets-api


    【解决方案1】:
    import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
    GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream(CREDENTIALS_FILE_PATH))
        .createScoped(Collections.singleton(SCOPES));
    
    • 或者,您也可以从 .p12 文件构建您的凭据:
    GoogleCredential credential = new GoogleCredential.Builder()
        .setTransport(httpTransport)
        .setJsonFactory(JSON_FACTORY)
        .setServiceAccountId(emailAddress)
        .setServiceAccountPrivateKeyFromP12File(new File("MyProject.p12"))
        .setServiceAccountScopes(Collections.singleton(YOUR SCOPE))
        .build();
    
    • 但是,如果您确实想使用 GoogleCredentials 并且在使用 HttpRequestInitializer 时遇到问题,您可以使用 HttpCredentialsAdapter

    【讨论】:

    • 谢谢,我去了HttpCredentialsAdapter,工作起来就像一个魅力。因为我想这将是未来的发展方向,所以我会保留它。
    • 有效。以下是在 Spring bean 中使用 HttpCredentialsAdapter 的方法: --- @Bean fun getGoogCreds(creds: GoogleCredentials): HttpCredentialsAdapter { return HttpCredentialsAdapter(creds) }