当前位置: 首页 > 知识库问答 >
问题:

如何使用服务帐户凭据将文件上载到Google Team Drive中的文件夹?

宋和颂
2023-03-14

我正在尝试使用Google Drive Java API v3为我们的应用程序实现一项新服务,该服务负责将文件上传到Google Team Drive中的特定文件夹。我使用我的公司专门为这个项目创建的服务帐户,还从谷歌开发者控制台生成了一个包含私钥的JSON文件。我还使用该服务帐户的电子邮件将该文件夹共享给该服务帐户xxxxx@xxxx.iam.gserviceaccount.com并授予Content Manager共享团队驱动的权限。此外,由于一些原因,G套件域范围的权限尚未授予该服务帐户。

我想在这里实现什么:
我想使用服务帐户生成的私钥构建并返回一个授权的Google Drive客户端服务,从而能够将上传文件的请求发送到Google Team Drive中的文件夹。

我目前使用的:

  • IntelliJ IDEA IntelliJ IDEA 2018.1.7(终极版)
  • Spring靴2
  • Java 10.0.1

问题是什么:
我无法成功返回授权的谷歌硬盘客户端服务,上传文件的请求根本没有发送。更令人困惑的是,没有抛出异常。但是,凭据会成功返回,其中包含访问令牌和过期时间。

我已经读到的内容:
使用OAuth2。0用于服务器到服务器应用程序:https://developers.google.com/identity/protocols/OAuth2ServiceAccount

Java Quickstart关于创建对驱动器API的简单请求:https://developers.google.com/drive/api/v3/quickstart/java

驱动器API的JavaDoc参考:https://developers.google.com/resources/api-libraries/documentation/drive/v3/java/latest/

如何上传文件到谷歌驱动器与服务号凭据:如何上传文件到谷歌驱动器与服务号凭据

如何使用Google Drive的服务帐户访问Team Drive。NET API v3:如何使用Google Drive的服务帐户访问Team Drive。NET API v3

身份验证使用Google drive API client library for Java上载硬盘中的文件身份验证使用Google drive API client library for Java上载硬盘中的文件

我已经尝试过的:

  • 使用GoogleCredential类返回凭据(该类似乎已被弃用:https://googleapis.dev/java/google-api-client/latest/)

ContractStateUpdateService的相关部分。爪哇:

File fileMetadata = new File();
fileMetadata.setName(fileTitle);
// setting the id of folder to which the file must be inserted to
fileMetadata.setParents(Collections.singletonList("dumbFolderId"));
fileMetadata.setMimeType("application/pdf");

byte[] pdfBytes = Base64.getDecoder().decode(base64File.getBytes(StandardCharsets.UTF_8));
InputStream inputStream = new ByteArrayInputStream(pdfBytes);

// decoding base64 to PDF and its contents to a byte array without saving the file on the file system
InputStreamContent mediaContent = new InputStreamContent("application/pdf", inputStream);

logger.info("Starting to send the request to drive api");
File file = DriveUtils.getDriveService().files().create(fileMetadata, mediaContent).execute();
logger.info("Succesfully uploaded file: " + file.getDriveId());

胡说八道。爪哇:

public class DriveUtils {

    private static final String APPLICATION_NAME = "Google Drive Service";

    // setting the Drive scope since it is essential to access Team Drive
    private static List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE);

    // private key is stored at the root of the project for now
    private static String PRIVATE_KEY_PATH = "/path/to/private_key.json";
    private static final Logger logger = LoggerFactory.getLogger(DriveUtils.class);

    // build and return an authorized drive client service
    public static Drive getDriveService() throws IOException, GeneralSecurityException {
        final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
        GoogleCredentials credentials;

        try (FileInputStream inputStream = new FileInputStream(PRIVATE_KEY_PATH)){
            credentials = ServiceAccountCredentials.fromStream(inputStream).createScoped(SCOPES);
            credentials.refreshIfExpired();
            AccessToken token = credentials.getAccessToken();
            logger.info("credentials: " + token.getTokenValue());
        } catch (FileNotFoundException ex) {
            logger.error("File not found: {}", PRIVATE_KEY_PATH);
            throw new FileNotFoundException("File not found: " + ex.getMessage());
        }

        logger.info("Instantiating client next");
        // Instantiating a client: this is where the client should be built but nothing happens... no exceptions!
        Drive service = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, (HttpRequestInitializer) credentials)
                .setApplicationName(APPLICATION_NAME)
                .build();
        // this log should appear immediately after the client has been instantiated but still nothing happens
        logger.info("Client instantiated");

        return service;
    }

}

波姆。xml:

<!-- https://mvnrepository.com/artifact/com.google.api-client/google-api-client -->
        <dependency>
            <groupId>com.google.api-client</groupId>
            <artifactId>google-api-client</artifactId>
            <version>1.29.2</version>
        </dependency>

        <dependency>
            <groupId>com.google.apis</groupId>
            <artifactId>google-api-services-drive</artifactId>
            <version>v3-rev165-1.25.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.google.auth/google-auth-library-oauth2-http -->
        <dependency>
            <groupId>com.google.auth</groupId>
            <artifactId>google-auth-library-oauth2-http</artifactId>
            <version>0.16.1</version>
        </dependency>


        <!-- https://mvnrepository.com/artifact/org.springframework.security.oauth/spring-security-oauth2 -->
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.3.6.RELEASE</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.google.oauth-client/google-oauth-client-jetty -->
        <dependency>
            <groupId>com.google.oauth-client</groupId>
            <artifactId>google-oauth-client-jetty</artifactId>
            <version>1.29.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
        </dependency>

我肯定我错过了一些东西,我为我的英语提前道歉。任何帮助都将不胜感激。

共有1个答案

穆正祥
2023-03-14

谢谢你的评论,这里的建议很有帮助,值得研究。然而,我在这里给出的解决方案并不能直接回答我的问题,即我的代码如何或为什么没有产生任何错误消息。现在,这是我解决这个问题的解决方案:

  1. 启用驱动器API。在阅读了大量关于从服务帐户向驱动API发出请求的文章和文档后,很明显,如果我们没有从Google API控制台启用驱动API,我的代码将无法工作

波姆。xml:

 <dependency>
    <groupId>com.google.api-client</groupId>
    <artifactId>google-api-client</artifactId>
    <version>1.23.0</version>
 </dependency>
 <dependency>
    <groupId>com.google.apis</groupId>
    <artifactId>google-api-services-drive</artifactId>
    <version>v3-rev110-1.23.0</version>
 </dependency>
 <dependency>
    <groupId>com.google.oauth-client</groupId>
    <artifactId>google-oauth-client-jetty</artifactId>
    <version>1.23.0</version>
 </dependency>

ContractStateUpdateService。爪哇:

File fileMetadata = new File();
fileMetadata.setName(fileTitle);

// setting the id of folder to which the file must be inserted to
fileMetadata.setParents(Collections.singletonList("dumbTeamDriveId"));
fileMetadata.setMimeType("application/pdf");

// decoding base64 to PDF and its contents to a byte array without saving the file on the file system
byte[] pdfBytes = Base64.getDecoder().decode(base64File.getBytes(StandardCharsets.UTF_8);
InputStream inputStream = new ByteArrayInputStream(pdfBytes);
InputStreamContent mediaContent = new InputStreamContent("application/pdf", inputStream);

try {
  // upload updated agreement as a PDF file to the Team Drive folder
  DriveUtils.getDriveService().files().create(fileMetadata, mediaContent)
                            .setSupportsTeamDrives(true) // remember to set this property to true!
                            .execute();
} catch (IOException ex) {
  logger.error("Exception: {}", ex.getMessage());
  throw new IOException("Exception: " + ex.getMessage());
} catch (GeneralSecurityException ex) {
  logger.error("Exception: {}", ex.getMessage());
  throw new GeneralSecurityException("Exception: " + ex.getMessage());
}

DriveUtils类的更新代码:

// create and return credential
private static Credential getCredentials() throws IOException {
    GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream(PRIVATE_KEY_PATH))
                .createScoped(SCOPES);

    return credential;
}

// build and return an authorized drive client service
public static Drive getDriveService() throws IOException, GeneralSecurityException {
    final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();

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

    return service;
}
 类似资料:
  • 我想上传文件到我的谷歌驱动器使用谷歌服务号凭据。 我从谷歌开发者控制台下载了一个JSON文件作为凭证,并从中获得了凭证。 这是我的代码片段。 代码运行,没有错误,但是我找不到上传到我的Google Drive帐户的文件。我不知道为什么文件没有上传。你愿意帮我解决这个问题吗?

  • 我正在构建一个功能,将文件从我的web应用程序上传到我的客户google drive。我不希望应用程序对用户进行身份验证。谁曾经上传过我文件中的任何文件?我想上传到我客户的谷歌硬盘。 我假设服务帐户是用于此目的的帐户。我说得对吗? 当我使用以下代码上传文件时,它会成功上传,但在“我的驱动器”下不可见。然后我添加了一个权限,基本上与我的gmail帐户共享该文件。然后它在“与我共享”部分可见。 我希望

  • 我正在构建一个需要读取普通Gmail收件箱(不是域的一部分)的Web服务。 代码: 错误: 我看不出这有什么原因不起作用,但读完这篇文章后,你似乎不能在个人@gmail帐户上使用服务帐户凭据。有谁知道这是真的还是我做错了什么? 感谢您的帮助! 更新 如果我将更改为,我可以查看邮件,但无法修改标签,这是我的要求。

  • 我花了几个小时试图将文件上载到本地服务器文件夹,但比预期的困难,请帮助。 在我的前端下面插入文件 下面是我的控制器

  • 我有一个将文件上传到服务器的api。我需要让iphone成为一个将文件从dropbox传输到服务器的应用程序。 我的问题是,我是否需要将文件从dropbox/box帐户下载到iphone,然后使用api上传到我的服务器? 或者我可以跳过将文件下载到设备并直接从dropbox/box帐户上传到自定义服务器的过程吗? 或者可以选择在iphone和dropbox之间只同步少数文件,然后将文件的本地副本上

  • 我无法使用服务帐户插入google drive。相反,我可以使用相同的服务帐户从google drive下载和更新文件,而不会出现任何问题。我通过转到[我的项目]从特定用户(我们称之为用户“X”)的帐户中创建了服务帐户- 然后,我专门转到用户“X”的MyDrive上的一个文件夹,并将该文件夹与OAuth2的“创建新客户端ID”步骤生成的服务帐户电子邮件地址共享。我确保指定该文件夹的服务帐户权限为“