0

내 회사의 Google 드라이브 폴더 중 하나에 파일을 업로드하려고하는데 클라이언트의 개입없이이 작업을 수행하지 못했습니다. 그래서, 사용할 때마다이 :Google 드라이브 API REST V2 파일을 폴더에 넣지 못했습니다.

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 ="[email protected]"; 

    /** 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를 찾을 수 있고 성공적으로 파일을 삽입 할 수 있습니다. 그러나 두 번째 방법에서는 파일을 서비스 계정에 삽입하려고합니다. 액세스 할 수없는 드라이브 공간 (드라이브의 루트에 드라이브를 삽입하려고하면이 드라이브가 완벽 해집니다. y, 그러나 내 루트에서 파일을 볼 수 없습니다.)

결국 내 질문은 수동 승인을 수행하지 않고 회사의 드라이브 폴더에 파일을 삽입하는 방법이 있습니까? 즉, 내 앱이 사용자 상호 작용없이 회사의 드라이브에 파일을 업로드하도록 허용하려면 어떻게해야합니까?

나는 전에 시도한 것처럼 client_secrets 방식이 작동하지 않을 것이라고 생각하며 코드를 처음 실행할 때 수동으로 수동으로 요청합니다. Linux 서버의 JAR 파일에서 코드를 실행하고 있기 때문에 이는 실용적이지 않고 저에게 효과적이지 않습니다.

감사합니다.

답변

0

404: File not found은 사용자에게 파일에 대한 읽기 권한이 없거나 파일이 존재하지 않음을 의미합니다.

파일 메타 데이터를 요청할 때 올바른 access_token을 제공했는지 확인하십시오. 인증 코드 인 access_token을 재생성하십시오. 사용자 대신 사용자의 요청이 authorize and authenticate이어야하며 클라이언트 ID는 사용자의 문서에 액세스하기에 충분하지 않습니다.

문서는 파일에 대한 읽기 권한이 없거나 파일이 존재하지 않는다고 사용자에게보고 할 것을 제안합니다. 소유자에게 파일에 대한 권한을 요청해야한다고 설명합니다.