使用Google API v3 JAVA列出Google云端硬盘文件夹中的文件

gopyfrb3  于 2023-01-07  发布在  Java
关注(0)|答案(2)|浏览(155)

我试图列出在谷歌驱动器文件夹中找到的所有文件,查询似乎工作,但当我试图使用.getFiles()获得文件列表的列表是空的。

private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
    private static final String CREDENTIALS_FILE_PATH = "/serv_acc.json";
    private static final String SERVICE_ACCOUNT = "xxxxxxxxx.iam.gserviceaccount.com";

    private static final String APPLICATION_NAME = "ZZZ-bco-eXXX_oo";
    private static final List<String> SCOPES = Arrays.asList(DriveScopes.DRIVE);
    private static final String ROOT_FOLDER = "XXXXXXXXXXXXXX";

    private static final String projection = "nextPageToken, files(id, name)";
    
    private static Drive driveService;
 

public static void buildApiService() throws IOException, GeneralSecurityException {
        final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
        InputStream resourceAsStream = GoogleDriveApplication.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
        HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(
                ServiceAccountCredentials.fromStream(resourceAsStream).createScoped(SCOPES).createDelegated(SERVICE_ACCOUNT));
        driveService = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY,                       requestInitializer).setApplicationName(APPLICATION_NAME).build();
    }

public static List<File> getChildren(String id) throws IOException {

        String query = "'" + id + "'" + " in parents";

        FileList directChildren = driveService.files().list()
                .setQ(query).setFields(projection).execute();

        System.out.println(directChildren.isEmpty()); // False
        System.out.println(directChildren.size()); // 3
        System.out.println(directChildren.getFiles().isEmpty()); // True
        ...
    }

public static void main(String[] args) throws GeneralSecurityException, IOException {

        buildApiService();
       ....
    }

该文件夹如下所示:
1个子文件夹,1个zip(1,63 Go),1个Xlsx(200Kb)!
请注意:
。当其他进程使用相同的凭据时,相同的凭据在相同的文件夹中起作用(Python代码)
。相同的Java代码可用于其他文件夹
编辑2:我用Python编写了同样的代码。没有对证书或Google驱动器文件夹(权限,权限等)进行任何更改,它工作正常。

# The needed import for service account credentials:
from oauth2client.service_account import ServiceAccountCredentials
from googleapiclient.http import MediaIoBaseDownload
from apiclient.discovery import build
from getfilelistpy import getfilelist
import io
import flatdict
import os
scope = ['https://www.googleapis.com/auth/drive']
# Parsing JSON credentials for a service account:
credentials = ServiceAccountCredentials.from_json_keyfile_name('C:/serv_acc.json', scope)
service = build('drive', 'v3', credentials=credentials)
topFolderId = 'XXXXXXXXXXXXXX'  
resource = {
    "service_account": credentials,
    "id": topFolderId,
    "fields": "files(id,name)",
}
res = getfilelist.GetFileList(resource)
print(dict(res))

服务帐户是有权访问对外部用户打开的文件夹的用户组的一部分。

ubbxdtey

ubbxdtey1#

如果您收到的200响应为空列表,并且您知道该文件夹包含一些文件,则最可能的原因是该文件夹未与服务帐户共享。
From what I see in your code, when setting up the credentials you used createDelegated(SERVICE_ACCOUNT) , where SERVICE_ACCOUNT is just the xxxxxxxxx.iam.gserviceaccount.com address of the service account that you're using. The documentation states that if the service account has domain-wide delegation you have to specify the user that you want to impersonate (so if the folder is owned by user@yourdomain.com, you have to use that address instead):
如果凭据支持域范围的委托,则创建标识的副本,以便它模拟指定的用户;否则,返回相同的示例。
因此,如果你已经为你的服务帐户设置了域范围的委派,你需要首先模拟文件夹的所有者,或者其他有权访问该文件夹的人。否则,你需要首先使用你的服务帐户share该文件夹。

参考文献:
d5vmydt9

d5vmydt92#

服务帐户是一个虚拟用户,它有自己的Google Drive帐户。它不返回文件的原因是你还没有上传任何文件。
如果你的个人google drive账户上有一个目录,你可以使用服务账户的电子邮件地址,并与服务账户共享该目录,这样服务账户就可以访问该目录中的任何文件。
如果你有一个google workspace帐户,你也可以配置域范围的授权,允许服务帐户访问workspace域中的任何内容。

相关问题