【问题标题】:Getting 401 Unauthorized from Google API Resumable Update从 Google API 可恢复更新获取 401 Unauthorized
【发布时间】:2012-04-14 13:12:28
【问题描述】:

我正在尝试将上传到 Google Docs 的任意文件集成到现有应用程序中。在强制使用可恢复上传之前,这曾经有效。我正在使用 Java 客户端库。

应用程序分两步进行上传: - 获取文件的resourceId - 上传数据

为了获取 resourceId,我上传了一个 0 大小的文件(即 Content-Length=0)。我在可恢复 URL 中传递 ?convert=false(即https://docs.google.com/feeds/upload/create-session/default/private/full?convert=false)。

我将“application/octet-stream”作为内容类型传递。这似乎可行,尽管我确实得到了不同的资源 ID - “文件:...”资源 ID 用于图像之类的东西,但“pdf:....”资源 ID 用于 PDF。

第二步根据之前获取的resourceId构造一个URL,并进行搜索(getEntry)。 URL 格式为https://docs.google.com/feeds/default/private/full/file%3A.....

找到条目后,ResumableGDataFileUploader 将使用正在上传的文件中的实际数据更新内容(0 字节文件)。构建 ResumableGDataFileUploader 实例时,此操作失败并返回 401 Unauthorized response。

我已经尝试过 ?convert=false 以及 ?new-revision=true 以及这两种方法。结果是一样的。

相关代码:

MediaFileSource mediaFile = new MediaFileSource(
    tempFile, "application/octet-stream");

final ResumableGDataFileUploader.Builder builder = 
    new ResumableGDataFileUploader.Builder(client, mediaFile, documentListEntry);
builder.executor(MoreExecutors.sameThreadExecutor());
builder.requestType(ResumableGDataFileUploader.RequestType.UPDATE);

// This is where it fails
final ResumableGDataFileUploader resumableGDataFileUploader = builder.build();
resumableGDataFileUploader.start();

return tempFile.length();

“客户端”是 DocsService 的一个实例,配置为使用 OAuth。它用于在给定代码段之前查找“documentListEntry”。

我必须明确指定请求类型,因为客户端库代码似乎包含一个错误,导致“更新现有条目”情况下出现 NullPointerException。

我怀疑问题出在操作序列上(上传 0 字节文件以获取 resourceId,然后使用实际文件进行更新),但我不知道为什么它不起作用。

请帮忙?

【问题讨论】:

    标签: google-docs-api


    【解决方案1】:

    此代码 sn-p 适用于我使用 OAuth 1.0 和 OAuth 2.0:

    static void uploadDocument(DocsService client) throws IOException, ServiceException,
        InterruptedException {
      ExecutorService executor = Executors.newFixedThreadPool(10);
    
      File file = new File("<PATH/TO/FILE>");
      String mimeType = DocumentListEntry.MediaType.fromFileName(file.getName()).getMimeType();
    
      DocumentListEntry documentEntry = new DocumentListEntry();
      documentEntry.setTitle(new PlainTextConstruct("<DOCUMENT TITLE>"));
    
      int DEFAULT_CHUNK_SIZE = 2 * 512 * 1024;
      ResumableGDataFileUploader.Builder builder =
          new ResumableGDataFileUploader.Builder(
              client,
              new URL(
                  "https://docs.google.com/feeds/upload/create-session/default/private/full?convert=false"),
              new MediaFileSource(file, mimeType), documentEntry).title(file.getName())
              .requestType(RequestType.INSERT).chunkSize(DEFAULT_CHUNK_SIZE).executor(executor);
    
      ResumableGDataFileUploader uploader = builder.build();
      Future<ResponseMessage> msg = uploader.start();
      while (!uploader.isDone()) {
        try {
          Thread.sleep(100);
        } catch (InterruptedException ie) {
          throw ie; // rethrow
        }
      }
    
      DocumentListEntry uploadedEntry = uploader.getResponse(DocumentListEntry.class);
      // Print the document's ID.
      System.out.println(uploadedEntry.getId());
      System.out.println("Upload is done!");
    }
    

    【讨论】:

    • 谢谢,但这并不能回答我的问题。是的,“一次性”上传有效。我目前无法使用它。我需要创建一个条目来获取文档 id,然后在代码后面的另一个地方,通过 id 搜索这个条目并上传实际内容。我试图在原始问题中描述的过程的“第一步”实际上与您提供的代码相同,但我遇到了“第二步”的问题 - 使用内容更新条目。跨度>
    • 对于更新,您可以使用从 API 检索到的 DocumentListEntry 而不是实例化一个新条目,并使用 RequestType.UPDATE 作为请求类型。
    • 嗯,您是否看过原始问题并查看了代码 sn-p?我正在从 API 中检索条目,并且我使用 UPDATE 作为请求类型。它以“未授权”响应失败。
    • 我用 OAuth 2.0 尝试了这段代码来更新文件的内容,它运行良好。然后我将授权机制更改为 OAuth 1.0,确实得到了未经授权的响应。我会调查这个问题,与此同时,你能切换到 OAuth 2.0 吗?
    • 我发现问题出在哪里。如果您从源代码运行客户端库,请删除此line;该存储库将很快更新。同样,迁移到 OAuth 2.0 将是一个更好的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-04
    • 2013-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-30
    • 2021-06-02
    相关资源
    最近更新 更多