尝试通过 Google Drive API 获取文档元数据时出现 404 错误

2024-04-06

我正在使用进行身份验证域范围的委派 https://developers.google.com/drive/web/delegation.

我正在恢复谷歌驱动器服务,如下所示:com.google.api.services.drive.Drive@6ebd27b9

这是我尝试检索的文件的链接:https://docs.google.com/a/rmi.org/document/d/1JRS8SLzaAD2U4cG-GbDMbVN25Dp6f_uUYyl6ERMPAno/edit

我将此值作为文件 ID 传递:1JRS8SLzaAD2U4cG-GbDMbVN25Dp6f_uUYyl6ERMPAno.

当代码到达这一行时:File file = service.files().get(fileId).execute();

我收到此错误:

An error occured: com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 OK
{
"code" : 404,
"errors" : [ {
"domain" : "global",
"message" : "File not found: 1JRS8SLzaAD2U4cG-GbDMbVN25Dp6f_uUYyl6ERMPAno",
"reason" : "notFound"
 } ],

当我尝试使用底部的工具查找有问题的文件时这一页 https://developers.google.com/drive/v2/reference/files/get,如果我打开 Oauth 2.0,我会收到 200 响应代码以及有关相关文件的信息。

我在这里看过很多类似的问题,包括this https://stackoverflow.com/questions/21188752/get-childrens-files-from-a-an-id-folder-in-google-drive问题,但我看不出我设置权限的方式有什么问题:

  • 对于我的项目,Drive API 和 Drive SDK 均位于 API 和 Auth 下。
  • 在“凭据”下,我可以看到我的客户 ID、电子邮件地址和公钥指纹
  • 我还在我的域的管理控制台上验证了在“安全”>“API 参考”下,选中了“启用 API 访问”。
  • 安全 > 高级设置 > 管理 API 客户端访问添加了以下范围:https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive与服务帐户的客户端 ID。
  • Security > Advanced > Manage Oauth Domain key:
    • 选中“启用此消费者密钥”复选框。
    • 有一个 oAuth 消费者密码。
    • 没有 X.509 证书。
    • 未选中“两条腿 OAuth 访问控制允许访问所有 API”。

这是我获得驱动服务的地方:

        public static Drive getDriveService() throws GeneralSecurityException,
    IOException, URISyntaxException {

  HttpTransport httpTransport = new NetHttpTransport();
  JacksonFactory jsonFactory = new JacksonFactory();
  GoogleCredential credential = new GoogleCredential.Builder()
      .setTransport(httpTransport)
      .setJsonFactory(jsonFactory)
      .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
      //.setServiceAccountScopes(DriveScopes.DRIVE)
      .setServiceAccountScopes(SCOPE)
      .setServiceAccountPrivateKeyFromP12File(
          new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH))
      .build();
  Drive service = new Drive.Builder(httpTransport, jsonFactory, null)
      .setHttpRequestInitializer(credential).build();
  return service;

我将这些变量定义如下:

/** Email of the Service Account */
private static final String SERVICE_ACCOUNT_EMAIL = "[email protected] /cdn-cgi/l/email-protection";

/** Path to the Service Account's Private Key file */
private static final String SERVICE_ACCOUNT_PKCS12_FILE_PATH = "/actualpathhere/HowToListing/war/resources/actualpd12filename.p12"; 
private static final List<String> SCOPE = Arrays.asList("https://www.googleapis.com/auth/drive.readonly");

这是我尝试获取文件元数据的地方:

private static List<File> retrieveAllFiles(Drive service) throws IOException {
        List<File> result = null;
        try {
            String fileId = "1JRS8SLzaAD2U4cG-GbDMbVN25Dp6f_uUYyl6ERMPAno";
            File file = service.files().get(fileId).execute();
            System.out.println("Title: " + file.getTitle());
            System.out.println("Description: " + file.getDescription());
            System.out.println("MIME type: " + file.getMimeType());

          } catch (IOException e) {
            System.out.println("An error occured: " + e);
          }


        return result;
      }

谁能给我任何关于可能发生的事情的提示?


EDITED

事实证明,所有的安全措施都是为了转移注意力。缺少的关键是有效的用户电子邮件地址。首先,功能代码:

import java.io.IOException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.Arrays;

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;


public class DriveCommandLine {


  private static String SERVICE_ACCOUNT_EMAIL  = "[email protected] /cdn-cgi/l/email-protection";
  private static final String SERVICE_ACCOUNT_PKCS12_FILE_NAME = "a_file_name.p12";
  private static String SERVICE_ACCOUNT_PKCS12_FILE_PATH; 

  public static void main(String[] args) throws IOException {
    try {
      //I did this stuff for the p12 file b/c I was having trouble doing this all from command line (first time)
      URL location = DriveCommandLine.class.getProtectionDomain().getCodeSource().getLocation();
      SERVICE_ACCOUNT_PKCS12_FILE_PATH = location.getFile() + SERVICE_ACCOUNT_PKCS12_FILE_NAME;

      Drive drive = DriveCommandLine.getDriveService("[email protected] /cdn-cgi/l/email-protection");
      DriveCommandLine.printFile(drive, "THE_ID_OF_THE_FILE");
    } catch (GeneralSecurityException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  //From https://developers.google.com/drive/web/delegation#instantiate_a_drive_service_object
  /**
   * Build and returns a Drive service object authorized with the service accounts
   * that act on behalf of the given user.
   *
   * @param userEmail The email of the user.
   * @return Drive service object that is ready to make requests.
   */
  public static Drive getDriveService(String userEmail) throws GeneralSecurityException, IOException {
    HttpTransport httpTransport = new NetHttpTransport();
    JacksonFactory jsonFactory = new JacksonFactory();
    GoogleCredential credential = new GoogleCredential.Builder().setTransport(httpTransport)
                                                                .setJsonFactory(jsonFactory)
                                                                .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
                                                                .setServiceAccountScopes(Arrays.asList(new String[] {DriveScopes.DRIVE}))
                                                                .setServiceAccountUser(userEmail)
                                                                .setServiceAccountPrivateKeyFromP12File(new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH))
                                                                .build();
    Drive service = new Drive.Builder(httpTransport, jsonFactory, null).setHttpRequestInitializer(credential).build();
    return service;
  }
  // From the code box at https://developers.google.com/drive/v2/reference/files/get
  /**
   * Print a file's metadata.
   *
   * @param service Drive API service instance.
   * @param fileId ID of the file to print metadata for.
   */
  private static void printFile(Drive service, String fileId) {

    try {
      File file = service.files().get(fileId).execute();

      System.out.println("Title: " + file.getTitle());
      System.out.println("Description: " + file.getDescription());
      System.out.println("MIME type: " + file.getMimeType());
    } catch (IOException e) {
      System.out.println("An error occured: " + e);
    }
  }
}

缺失的行是setServiceAccountUser(userEmail)这是针对有效的系统用户的。

通过有效用户,我获得了文件详细信息。

对于无效用户,我得到了

An error occured: com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
  "error" : "invalid_grant",
  "error_description" : "Not a valid email."
}

而且,对于没有访问权限或未设置线路的用户,我得到了

An error occured: com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
{
  "code" : 404,
  "errors" : [ {
    "domain" : "global",
    "message" : "File not found: THE_FILE_ID",
    "reason" : "notFound"
  } ],
  "message" : "File not found: THE_FILE_ID"
}

注意:请务必遵循以下每一个小步骤执行 Google Apps 域范围内的授权 https://developers.google.com/drive/web/delegation#instantiate_a_drive_service_object因为这就是我最终得到解决方案和所有正确密钥的地方(不需要我最初想象的那么多!)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尝试通过 Google Drive API 获取文档元数据时出现 404 错误 的相关文章

随机推荐

  • 实体框架和 WCF(返回附加到上下文的实体)

    我有一个 WCF 服务 它在我的 Repository 对象之一中调用以下方法 以在数据库中创建一个新的销售对象 public static Sale New Sale sale using var ctx new DBcontext ct
  • 如何更改 Minikube 中 api-server 的身份验证机制?

    我有一个本地 minikube 安装 我想更改 api server 的身份验证机制并重新启动并测试它 我读过的所有文档都缺少此信息 是的你可以 kubernetes API 服务器 控制器管理器和调度程序都作为 minikube 中的静态
  • 有没有办法对 unsigned long long A 和 B 执行 (A*B) mod M 而不会溢出?

    我不想经历在 Windows 上安装 GMP 的噩梦 我有两个数字A和B unsigned long longs 最多 10 10 左右的数量级 但即使在这样做时 A M B M M 我得到整数溢出 是否有用于计算的自制函数 A B M对于
  • 特定于操作系统的 CSS?

    过去 我发现不同平台上相同浏览器中的 CSS 几乎没有区别 Mac 上 Safari 上的页面通常与 Windows 上的 Safari 看起来相同 FF Win 与 FF Mac 也是如此 然而 现在我遇到了一个问题 与 PC 浏览器相比
  • 为什么重复捕获组会返回这些字符串?

    有人可以解释为什么以下返回 cc 吗 gt gt gt re match aabbcc group 1 cc 有人告诉我 因为它将每场比赛放入组 1 所以最后一场比赛是 cc 真的吗 那么下面怎么解释呢 gt gt gt re match
  • .net 程序集清单中是否提升了依赖项?

    我使用 VS2010 构建了一个程序集 它具有对 NET 4 0 的普通引用 它还引用了 Ionic Zip 后者引用了 NET 2 0 当我使用 ildasm 查看清单时 我发现 NET 的两个版本都是我的程序集的直接依赖项 并且在 Io
  • Azure 服务总线消息队列用户错误指标

    我正在帮助调查和诊断我们遇到的一些问题 并注意到服务总线队列上的用户错误指标正在发生变化 我想确切地知道这个指标的含义 如文档所示https learn microsoft com en us azure service bus messa
  • 如何通过网页将参数传递到 PHP 脚本中?

    每当网页加载时我都会调用 PHP 脚本 但是 PHP 脚本需要运行一个参数 我在测试脚本时通常通过命令行传递该参数 每次加载页面时运行脚本时如何传递此参数 假设您在命令行上传递参数 如下所示 php path to wwwpublic pa
  • SQL Server分页查询

    呃呃呃 我已经为此苦苦挣扎了很长时间 我可以用 MySQL 轻松做到这一点 但用 SQL Server 就不行 这是应该连接在一起的简化表格 通过使用内连接语法将所有这些组合起来 我必须编写一个查询以用于将来的分页 顺便说一句 PHP 假设
  • 从字典和数组的 plist 中读取/写入数据,并将不同级别加载到 TableView 中

    我对使用属性列表有点困惑 我已经阅读了有关该主题的大多数其他问题 但我仍然很困惑 因为它们只进入一层 因此任何帮助将不胜感激 我想加载一个存储数据的plist 如下所示 我的故事板中有三个视图控制器 两个 TableView 控制器和一个空
  • Android获取当前歌曲播放和歌曲更改事件,例如Musixmatch

    我想要实现的目标非常相似是在做 我需要在音乐开始播放以及歌曲更改时得到通知 所有这些都在服务中 因为我的应用程序可能会关闭 甚至 musicmatch 也会这样做 在上述情况下 即使 Musixmatch 应用程序未运行 当我在 Spoti
  • 如何从 XMLReader 获取属性

    我有一些 HTML 正在转换为Spanned using Html fromHtml 并且我在其中使用了一个自定义标签
  • 如何保持用户登录系统并仅在用户单击注销按钮后注销?

    我正在使用 microsoft asp net 身份的自定义实现 因为我有自定义表 这就是为什么我给出了所有方法的自定义实现IUserStore 和 IUserPasswordStore 问题是当用户登录时 10 15 分钟后登录用户 会话
  • Angular 模板中可观察对象上的 ObjectUnsubscribedErrorImpl

    我正在使用 Angular 11 并且正在使用以下命令访问组件模板中的可观察对象async pipe 路线的第一次加载 一切都工作得很好 没有错误 当我离开该页面并返回时 出现以下错误 组件模板 成分 import Component On
  • 使用 optaplanner 返回调度问题的多个解决方案

    强文本您好 Optaplanner 专家 我对 OptaPlanner 还很陌生 所以请原谅任何幼稚或基本的问题 我用它来安排 set of jobs A B and C which can be completed by 5 resour
  • 如何在android中禁用已经预订的时段

    我必须禁用已经预订的时段并仅向用户显示可用的时段 在回收站视图中 时间从 09 00Am 到 09 00Pm 可见 已预订的时段应处于禁用模式 并且用户只能选择可用的时段 在主要活动中 我存储从 09 00AM 到 09 00PM 的所有时
  • 如何将 SVN 修订号与我的 ASP.NET 网站同步?

    Stack Overflow 底部有一个颠覆版本号 svn 修订版 679 我想在我的应用程序中使用这种自动版本控制 NET Web Site Application Windows 窗体 WPD 项目 解决方案 我该如何实施 看起来杰夫正
  • 我怎样才能看到csrftoken?

    有没有办法直接在View中获取csrftoken 我想获取当前的 csrftoken 但有时会发生变化 因此从 Cookie 获取它不是一个好主意 有什么办法可以做到这一点吗 Thanks 我相信您正在寻找这个 django middlew
  • 在自定义列中显示日期范围 - 间隙和孤岛

    我有一个看起来像这样的表 Date Name 2017 01 07 A 2017 01 08 A 2017 01 09 A 2017 01 12 A 2017 01 07 B 2017 01 08 B 2017 01 09 B 我希望能够将
  • 尝试通过 Google Drive API 获取文档元数据时出现 404 错误

    我正在使用进行身份验证域范围的委派 https developers google com drive web delegation 我正在恢复谷歌驱动器服务 如下所示 com google api services drive Drive