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

时间:2014-10-22 16:04:19

标签: java google-drive-api

我正在使用domain-wide delegation进行身份验证。

我正在收回如下所示的google云端硬盘服务: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"
 } ],

当我尝试使用this page底部的工具找到相关文件时,如果我打开Oauth 2.0,我会收到200响应代码和有关该文件的信息。

我在这里看了很多类似的问题,包括this问题,但我在设置权限的方式上看不出任何错误:

  • 对于我的项目,Drive API和Drive SDK都在API和Auth。
  • 在凭据下,我看到了我的客户ID,电子邮件地址和公钥指纹
  • 我还在我的域管理控制台上验证了安全性>检查API参考,启用API访问。
  • 安全>高级设置>管理API客户端访问添加了以下范围:https://www.googleapis.com/auth/drive以及服务帐户的客户端ID。
  • 安全>高级>管理Oauth域密钥:
    • 选中“启用此消费者密钥”复选框。
    • 有一个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 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx@developer.gserviceaccount.com";

/** 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;
      }

任何人都可以给我任何关于可能发生的事情的提示吗?

1 个答案:

答案 0 :(得分:1)

<强> 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  = "11111-abc123@developer.gserviceaccount.com";
  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("valid-user@example.com");
      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"
}

注意:请确保您遵循Perform Google Apps Domain-Wide Delegation of Authority的每个小步骤,因为这是我最终获得解决方案和所有正确的密钥(不需要我最初想的那么多!)< / p>