2012-04-14 4 views
2

Я пытаюсь интегрировать загрузку произвольных файлов в Google Docs в существующее приложение. Это использовалось для работы перед использованием возобновляемой загрузки, стало обязательным. Я использую клиентские библиотеки Java.Получение 401 Несанкционированное обновление Google API Возобновляемое обновление

Приложение делает загрузку в 2 этапа: - получить RESOURCEID файла - загрузить данные

Чтобы получить RESOURCEID я отправляю файл с 0-размер (т.е. Content-Length = 0). Я передаю? Convert = false в возобновляемом URL (т. Е. https://docs.google.com/feeds/upload/create-session/default/private/full?convert=false).

Я передаю «приложение/октет-поток» как контент-тип. Кажется, что это работает, хотя я получаю разные ресурсы. Идентификаторы - файлы «file: ...» для таких вещей, как изображения, но «pdf: ...» resourceIds для PDF-файлов.

Второй шаг создает URL-адрес на основе полученного ранее ресурса и выполняет поиск (getEntry). URL-адрес находится в форме https://docs.google.com/feeds/default/private/full/file%3A .....

После того, как запись найдена, ResumableGDataFileUploader используется для обновления содержимого (0-байтовый файл) с фактическими данными из загружаемого файла. Эта операция завершается с ошибкой 401 Unauthorized при создании экземпляра ResumableGDataFileUploader.

Я пробовал с? 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, а затем обновить с фактическим файлом), но я не могу понять, почему он не работает.

Помогите?

ответ

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!"); 
} 
+0

Спасибо, но это не ответ на мой вопрос. Да, загружается «за один раз». Я не могу использовать это в данный момент. Мне нужно создать запись для получения идентификатора документа, затем в другом месте в коде, найти эту запись по идентификатору и загрузить фактический контент. «Первый шаг» процесса, который я пытался описать в исходном вопросе, практически идентичен представленному вами коду, но у меня возникла проблема с «вторым шагом» - обновлением записи с контентом. – techtime

+0

Для обновлений вы можете использовать DocumentListEntry, извлеченный из API, вместо создания нового экземпляра и использовать RequestType.UPDATE в качестве типа запроса. – Alain

+1

Хм, посмотрел ли вы оригинальный вопрос и просмотрел фрагмент кода? Я извлекаю запись из API, и я использую UPDATE в качестве типа запроса. Он терпит неудачу с ответом «НЕСАНКЦИОНИРОВАННЫЙ». – techtime

Смежные вопросы