2

我正在尝试将任意文件上传到 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)。

我将“应用程序/八位字节流”作为内容类型传递。这似乎可行,尽管我确实得到了不同的资源 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,然后使用实际文件进行更新),但我不知道为什么它不起作用。

请帮忙?

4

1 回答 1

3

此代码片段适用于我使用 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!");
}
于 2012-04-17T17:01:55.370 回答