Google Drive API REST V2将文件插入到找不到的文件夹文件中

时间:2016-07-19 10:31:19

标签: java file google-drive-api filenotfoundexception file-not-found

我正在尝试将文件上传到我公司的Google云端硬盘文件夹中,但我无法在没有客户干预的情况下实现这一目标。所以,每当我使用它时:

package sample;

import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
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;
import com.google.api.services.drive.model.ParentReference;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class DriveCommandLine_srive
{

    private static String CLIENT_ID = "myClientID.apps.googleusercontent.com";
    private static String CLIENT_SECRET = "myClientSecret";

    private static String REDIRECT_URI = "mything";

    public static void main( String[] args ) throws IOException
    {
        HttpTransport httpTransport = new NetHttpTransport( );
        JsonFactory jsonFactory = new JacksonFactory( );

        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder( httpTransport, jsonFactory, CLIENT_ID, CLIENT_SECRET, Arrays.asList( DriveScopes.DRIVE ) ).setAccessType( "online" ).setApprovalPrompt( "auto" ).build( );

        System.out.println("xxxxx : "  + DriveScopes.DRIVE);

        String url = flow.newAuthorizationUrl( ).setRedirectUri( REDIRECT_URI ).build( );
        System.out.println( "Please open the following URL in your browser then type the authorization code:" );
        System.out.println( "  " + url );
        BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
        String code = br.readLine( );

        GoogleTokenResponse response = flow.newTokenRequest( code ).setRedirectUri( REDIRECT_URI ).execute( );
        GoogleCredential credential = new GoogleCredential( ).setFromTokenResponse( response );

        // Create a new authorized API client
        Drive service = new Drive.Builder( httpTransport, jsonFactory, credential ).build( );

        insertFile(service, "Test File Drive", "This is a test file","myCompanysFolderID" , "text/plain", "./data/document.txt");

      }

    /**
     * Insert new file.
     *
     * @param service Drive API service instance.
     * @param title Title of the file to insert, including the extension.
     * @param description Description of the file to insert.
     * @param parentId Optional parent folder's ID.
     * @param mimeType MIME type of the file to insert.
     * @param filename Filename of the file to insert.
     * @return Inserted file metadata if successful, {@code null} otherwise.
     */
    private static File insertFile(Drive service, String title, String description,
        String parentId, String mimeType, String filename) {
      // File's metadata.
      File body = new File();
      body.setTitle(title);
      body.setDescription(description);
      body.setMimeType(mimeType);

      // Set the parent folder.
      if (parentId != null && parentId.length() > 0) {
        body.setParents(
            Arrays.asList(new ParentReference().setId(parentId)));
      }

      // File's content.
      java.io.File fileContent = new java.io.File(filename);
      FileContent mediaContent = new FileContent(mimeType, fileContent);
      try {
        File file = service.files().insert(body, mediaContent).execute();

        // Uncomment the following line to print the File ID.
        System.out.println("File ID: " + file.getId());

        return file;
      } catch (IOException e) {
        System.out.println("An error occured: " + e);
        return null;
      }
    }

}

我设法将文件成功上传到公司的文件夹,但我必须手动授权并每次粘贴代码。因此,我想以自动方式实现这一点,我改变了授权方法"使用服务帐户p12密钥授权客户端的密钥。这是更改后的新代码:

package sample;

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.ParentReference;


import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

public class DriveCommandLine2
{

    private static final String KEY_FILE_LOCATION = "data/myp12Key.p12";
    **//Note: this is the mail from a service account in my dev console, it is different from the OAuth client I use in the previous method.**
    private static final String SERVICE_ACCOUNT_EMAIL ="myServiceAccountEmail@appspot.gserviceaccount.com";

    /** Application name. */
    private static final String APPLICATION_NAME =
        "Drive API Java Quickstart";

    /** Global instance of the JSON factory. */
    private static final JsonFactory JSON_FACTORY =
        JacksonFactory.getDefaultInstance();

    public static void main( String[] args ) throws Exception
    {
        //Drive service = getServiceManual();
        Drive service = initializeDrive();
        //insertFile(service, "Test File Drive", "This is a test file","myCompanyFolderID" , "text/plain", "./data/document.txt");
        insertFile(service, "Test File Drive", "This is a test file","" , "text/plain", "./data/document.txt");
      }

    /**
     * Insert new file.
     *
     * @param service Drive API service instance.
     * @param title Title of the file to insert, including the extension.
     * @param description Description of the file to insert.
     * @param parentId Optional parent folder's ID.
     * @param mimeType MIME type of the file to insert.
     * @param filename Filename of the file to insert.
     * @return Inserted file metadata if successful, {@code null} otherwise.
     */
    private static File insertFile(Drive service, String title, String description,
        String parentId, String mimeType, String filename) {
      // File's metadata.
      File body = new File();
      body.setTitle(title);
      body.setDescription(description);
      body.setMimeType(mimeType);

      // Set the parent folder.
      if (parentId != null && parentId.length() > 0) {
        body.setParents(
            Arrays.asList(new ParentReference().setId(parentId)));
      }

      // File's content.
      java.io.File fileContent = new java.io.File(filename);
      FileContent mediaContent = new FileContent(mimeType, fileContent);
      try {
        File file = service.files().insert(body, mediaContent).execute();

        // Uncomment the following line to print the File ID.
        System.out.println("File ID: " + file.getId());

        return file;
      } catch (IOException e) {
        System.out.println("An error occured: " + e);
        return null;
      }
    }


    /////////////////////
    ///NEW GOOGLE ANALYTICS AUTH

    public static java.io.File convIs2File(InputStream inputStream, java.io.File file)
    {
        java.io.OutputStream outputStream = null;

        try {
            // write the inputStream to a FileOutputStream
            outputStream = new java.io.FileOutputStream(file);

            int read = 0;
            byte[] bytes = new byte[1024];

            while ((read = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read);
            }

            System.out.println("Done!");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    // outputStream.flush();
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
        return file;
    }
    private static Drive initializeDrive() throws Exception {
        // Initializes an authorized analytics service object.

        // Construct a GoogleCredential object with the service account email
        // and p12 file downloaded from the developer console.
        HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
        InputStream is = DriveCommandLine2.class.getClassLoader().getResourceAsStream(KEY_FILE_LOCATION);
        java.io.File f = java.io.File.createTempFile("myP12Key", ".p12");
        java.io.File f_used = convIs2File(is,f);
        GoogleCredential credential = new GoogleCredential.Builder()
                .setTransport(httpTransport)
                .setJsonFactory(JSON_FACTORY)
                .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
                .setServiceAccountPrivateKeyFromP12File(f_used)
                .setServiceAccountScopes(DriveScopes.all())
                .build();

        // Construct the Analytics service object.
        return new Drive.Builder(httpTransport, JSON_FACTORY, credential)
                .setApplicationName(APPLICATION_NAME).build();
    }


}

但是当我运行此代码时,我收到以下错误:

An error occured: com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
{
  "code" : 404,
  "errors" : [ {
    "domain" : "global",
    "location" : "file",
    "locationType" : "other",
    "message" : "File not found: myCompanyFolderID",
    "reason" : "notFound"
  } ],
  "message" : "File not found: myCompanyFolderID"
}

所以,我的猜测是,在以前的授权方式中,我使用我的Client_ID和Client_Secrets授权我的应用程序将内容插入我公司的驱动器空间,所以我找到myCompanyFolder并且我能够插入文件成功,但是,在第二种方法中,我试图将文件插入我无法访问的服务帐户驱动器空间(我知道这一点,因为当我尝试将其插入云端硬盘驱动器时root,它工作得很好,但是,我无法在根目录中看到该文件)。

所以最后,我的问题是,有没有办法将文件插入我公司的驱动器文件夹而不进行手动授权?也就是说,如何授权我的应用程序在没有人工干预的情况下将文件上传到公司的驱动器中?

我认为client_secrets方式在我之前尝试过时不会起作用,它要求我在第一次运行代码时手动完成。当我从Linux服务器上的JAR文件运行我的代码时,这根本不实用,对我来说不起作用。

谢谢!

1 个答案:

答案 0 :(得分:0)

404: File not found表示用户没有文件的读取权限,或文件不存在。

确保在发出文件元数据请求时提供正确的access_token。尝试重新生成授权码access_token。您需要代表用户authorize and authenticate提出请求,密钥和客户ID不足以访问用户的文档。

文档建议向用户报告他们没有对该文件的读访问权或该文件不存在。告诉他们他们应该要求所有者获得该文件的许可。