从Google API断续更新中获取未经授权的401 [英] Getting 401 Unauthorized from Google API Resumable Update
问题描述
我正在尝试将任意文件上传到Google Docs集成到现有应用程序中.在强制使用可恢复上传之前,此方法可以正常工作.我正在使用Java客户端库.
I am trying to integrate upload of arbitrary files to Google Docs into an existing application. This used to work before using resumable upload became mandatory. I am using Java client libraries.
该应用程序分两个步骤进行上传: -获取文件的resourceId -上传数据
The application is doing the upload in 2 steps: - get the resourceId of the file - upload the data
要获取resourceId,我正在上传一个大小为0的文件(即Content-Length = 0).我在可恢复的URL中传递?convert = false(即
To get the resourceId I am uploading a 0-size file (i.e. Content-Length=0). I am passing ?convert=false in the resumable URL (i.e. https://docs.google.com/feeds/upload/create-session/default/private/full?convert=false).
我将"application/octet-stream"作为内容类型传递.这似乎可行,尽管我确实获得了不同的resourceIds-用于图像之类的"file:..." resourceIds,但是对于PDF却是"pdf:...." resourceIds.
I am passing "application/octet-stream" as content-type. This seems to work, though I do get different resourcesIds - "file:..." resourceIds for things like images, but "pdf:...." resourceIds for PDFs.
第二步基于先前获得的resourceId构造URL并执行搜索(getEntry).该网址的格式为 https://docs.google.com/feeds/default/private/full/file%3A .....
The second step constructs a URL based on the resourceId obtained previously and performs a search (getEntry). The URL is in the form of https://docs.google.com/feeds/default/private/full/file%3A.....
找到该条目后,将使用ResumableGDataFileUploader使用要上传的文件中的实际数据来更新内容(0字节文件).构建ResumableGDataFileUploader实例时,此操作失败,并显示401未经授权的响应.
Once the entry is found the ResumableGDataFileUploader is used to update the content (0-byte file) with the actual data from the file being uploaded. This operation fails with 401 Unauthorized response when building ResumableGDataFileUploader instance.
我已经尝试使用?convert = false以及?new-revision = true了,并且两者都同时使用.结果是一样的.
I've tried with ?convert=false as well as ?new-revision=true and both of these at the same time. The result is the same.
相关代码段:
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".
The "client" is an instance of DocsService, configured to use OAuth. It is used to find "documentListEntry" immediately before the given piece of code.
我必须明确指定请求类型,因为似乎客户端库代码中包含一个导致更新现有条目"的情况的NullPointerException的错误.
I had to explicitly specify request type, since it seems the client library code contains a bug causing NullPointerException for "update existing entry" case.
我怀疑该问题特别是在一系列操作中(上传0字节文件以获取resourceId,然后使用实际文件进行更新),但我不知道为什么它不起作用.
I have a suspicion that the issue is specifically in the sequence of actions (upload 0-byte file to get the resourceId, then update with actual file) but I can't figure out why it doesn't work.
请帮助?
推荐答案
此代码段适用于使用OAuth 1.0和OAuth 2.0的我:
This code snippet works for me using OAuth 1.0 and 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!");
}
这篇关于从Google API断续更新中获取未经授权的401的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!