本文介绍了尝试通过谷歌驱动器API获取文档元数据时出现404错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用进行身份验证。



我回来了看起来像这样的谷歌驱动器服务: 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();



我得到这个错误:

 发生错误:com.google.api.client.googleapis.json.GoogleJsonResponseException:404 OK 
{
code:404,
errors:[{
domain:global,
message:File not found:1JRS8SLzaAD2U4cG-GbDMbVN25Dp6f_uUYyl6ERMPAno,
reason:notFound
$]],

当我尝试使用工具底部,如果我打开Oauth 2.0,我会得到返回一个200响应代码和有关该文件的信息。



我已经看过很多类似的问题,包括和服务帐户的客户端ID。

  • 安全性>高级>管理Oauth域密钥:


    • 选中启用此使用者密钥复选框。

    • 有一个oAuth消费者密码。

    • 没有X.509证书。




    未选中双腿OAuth访问控制允许访问所有API >

    这里是我获得驱动器服务的地方:

      public static Drive getDriveService )throws GeneralSecurityException,
    IOException,URISyntaxException {

    HttpTransport httpTransport = new NetHttpTransport();
    JacksonFactory jsonFactory = new JacksonFactory();
    GoogleCredential凭证=新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(凭证).build();
    退货服务;

    我有这些变量定义如下:

      / **服务帐户的电子邮件* / 
    private static final String SERVICE_ACCOUNT_EMAIL =xxxxxxxxxxxxxxxxxxxxxxxxxxxxx@developer.gserviceaccount.com;

    **服务帐户私钥文件的路径* /
    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)抛出IOException {
    List< File> result = null;
    尝试{
    字符串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());
    $ b $ catch(IOException e){
    System.out.println(发生错误:+ e);
    }


    返回结果;
    }

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

    解决方案

    EDITED

    一个红色的鲱鱼,事实证明。缺少的关键是有效的用户的电子邮件地址。首先,运行代码:

      import java.io.IOException; 
    import java.net.URL;
    import java.security.GeneralSecurityException;
    import java.util.Arrays;

    导入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;
    导入com.google.api.services.drive.Drive;
    导入com.google.api.services.drive.DriveScopes;
    导入com.google.api.services.drive.model.File;


    公共类DriveCommandLine {


    私有静态字符串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 {
    //我为p12文件做了这些事b / c我在做这件事时遇到了麻烦全部来自命令行(第一次)
    URL位置= DriveCommandLine.class.getProtectionDomain()。getCodeSource()。getLocation();
    SERVICE_ACCOUNT_PKCS12_FILE_PATH = location.getFile()+ SERVICE_ACCOUNT_PKCS12_FILE_NAME;

    驱动器驱动器= DriveCommandLine.getDriveService(valid-user@example.com);
    DriveCommandLine.printFile(驱动器,THE_ID_OF_THE_FILE);
    } catch(GeneralSecurityException e){
    // TODO自动生成的catch块
    e.printStackTrace();
    }
    }

    //从https://developers.google.com/drive/web/delegation#instantiate_a_drive_service_object
    / **
    *构建并返回授权服务帐户
    *代表给定用户的Drive服务对象。
    *
    * @param userEmail用户的电子邮件。
    * @return准备发出请求的驱动器服务对象。
    * /
    public static Drive getDriveService(String userEmail)throws GeneralSecurityException,IOException {
    HttpTransport httpTransport = new NetHttpTransport();
    JacksonFactory jsonFactory = new JacksonFactory();
    GoogleCredential凭证=新的GoogleCredential.Builder()。setTransport(httpTransport)
    .setJsonFactory(jsonFactory)
    .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
    .setServiceAccountScopes(Arrays.asList(new String [ ] {
    .setServiceAccountUser(userEmail)
    .setServiceAccountPrivateKeyFromP12File(new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH))
    .build();
    Drive service = new Drive.Builder(httpTransport,jsonFactory,null).setHttpRequestInitializer(credential).build();
    退货服务;
    }
    //从https://developers.google.com/drive/v2/reference/files/get
    / **
    中的代码框中打印文件元数据。
    *
    * @param服务Drive API服务实例。
    * @param fileId要打印元数据的文件的ID。
    * /
    private static void printFile(Drive service,String fileId){

    try {
    File file = service.files()。get(fileId)。执行();

    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(发生错误:+ e);
    }
    }
    }

    缺少的行是 setServiceAccountUser(userEmail)这是一个有效的系统用户。



    使用有效的用户,我得到了文件详细信息。 / p>

    使用无效用户时,我得到了

     发生错误:com .google.api.client.auth.oauth2.TokenResponseException:400错误请求
    {
    错误:invalid_grant,
    error_description:不是有效的电子邮件。
    }

    而且,对于没有访问权限的用户或者行不是set,我得到了

     发生了一个错误: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
    }

    注意:请确保您遵循,因为这是我最终获得解决方案和所有正确密钥的地方(不需要像我最初想象的那样多!)

    I am authenticating using domain-wide delegation.

    I am getting back the google drive service that looks like this: com.google.api.services.drive.Drive@6ebd27b9

    This is the link to the file I'm trying to retrieve: https://docs.google.com/a/rmi.org/document/d/1JRS8SLzaAD2U4cG-GbDMbVN25Dp6f_uUYyl6ERMPAno/edit

    I am passing in this value as the file ID: 1JRS8SLzaAD2U4cG-GbDMbVN25Dp6f_uUYyl6ERMPAno.

    When the code gets to this line: File file = service.files().get(fileId).execute();

    I get this error:

    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"
     } ],
    

    When I try to find the file in question using the tool at the bottom of this page, if I turn on Oauth 2.0, I get back a 200 response code and information about the file in question.

    I've looked at many similar questions on here including this question, but I can't see anything wrong in the way that I've set up my permissions:

    • For my project, both the Drive API and Drive SDK are on under APIs and Auth.
    • Under Credentials I see my client ID, Email addresss and Public Key fingerprints
    • I've also verified on my domain's admin console that under security > API reference, enable API access is checked.
    • Security > Advanced Settings > Manage API Client Access the following scope is added: https://www.googleapis.com/auth/drive with the service account's client ID.
    • Security > Advanced > Manage Oauth Domain key:
      • The "enable this consumer key" checkbox is checked.
      • There is an oAuth consumer secret code.
      • There is no X.509 certificate.
      • The "two legged OAuth access control Allow access to all APIs" is unchecked.

    Here is where I get the drive service:

            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;
    

    I have these variables defined as follows:

    /** 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");
    

    Here is where I am trying to get the file metadata:

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

    Can anyone give me any hints as to what might be going on?

    解决方案

    EDITED

    All the security was a red herring, it turns out. The key thing missing was a valid user's email address. First, functioning code:

    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);
        }
      }
    }
    

    The missing line was setServiceAccountUser(userEmail) which is for a valid system user.

    With a valid user, I got the file details.

    With an invalid user, I got

    An error occured: com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
    {
      "error" : "invalid_grant",
      "error_description" : "Not a valid email."
    }
    

    And, with a user who did not have access or when the line was not set, I got

    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"
    }
    

    NOTE: Just be sure you follow each little step at Perform Google Apps Domain-Wide Delegation of Authority since that is where I ended up getting the solution and all the right keys (didn't need as many as I initially thought!)

    这篇关于尝试通过谷歌驱动器API获取文档元数据时出现404错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

  • 08-27 21:33
    查看更多