调用Google Drive API获取全部文件夹仅返回一个的问题求助
Google Drive 文件夹列表获取异常排查求助
问题描述
已实现通过硬编码folderId将文件保存至Google Drive文件夹的功能,运行正常。但扩展获取所有文件夹列表的逻辑后,发现Google Drive中实际存在10个文件夹,接口仅返回1个结果,且无nextPageToken。
实现代码
获取文件夹方法
@Override public List<File> getAllFolders() throws IOException { Drive service = googleDriveProvider.getService(); List<File> files = new ArrayList<>(); String pageToken = null; do { FileList result = service.files().list() .setQ("mimeType='application/vnd.google-apps.folder'") .setSpaces("drive") .setSupportsAllDrives(true) .setIncludeItemsFromAllDrives(true) .setFields("nextPageToken, files(id, name, parents)") .setPageToken(pageToken) .execute(); for (File file : result.getFiles()) { System.out.printf("Found file: %s (%s)%n", file.getName(), file.getId()); } files.addAll(result.getFiles()); pageToken = result.getNextPageToken(); } while (pageToken != null); return files; }
GoogleDriveProvider类
@Service public class GoogleDriveProvider { private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance(); private static final Set<String> SCOPES = DriveScopes.all(); private static final String GET_DRIVE_SERVICE_ERROR_MESSAGE = "Getting instance of Google drive has failed, error: [%s]"; @Value("${google.drive.service.account.auth.json}") private String authJson; @Value("${info.app.name}") private String appName; public Drive getService() throws GoogleDriveException { try { final NetHttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport(); GoogleCredentials credentials = GoogleCredentials.fromStream( new ByteArrayInputStream(authJson.getBytes())).createScoped(SCOPES); credentials.refreshIfExpired(); HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials); return new Drive.Builder(httpTransport, JSON_FACTORY, requestInitializer) .setApplicationName(appName) .build(); } catch (IOException | GeneralSecurityException e) { throw new GoogleDriveException( format(GET_DRIVE_SERVICE_ERROR_MESSAGE, e.getMessage()), e); } } }
排查方向与解决方案
- 服务账号权限验证:从服务账号的auth JSON文件中提取
client_email字段对应的邮箱地址,确认Google Drive中的所有10个文件夹均已共享给该邮箱,并授予至少查看权限。服务账号拥有独立的Drive存储空间,未共享的文件夹无法被访问。 - 添加查询条件排除已删除项:在
setQ参数中补充and trashed=false,确保只返回未被删除的文件夹:.setQ("mimeType='application/vnd.google-apps.folder' and trashed=false") - 启用域范围授权并模拟用户(若适用):若目标文件夹属于域内用户的个人Drive而非服务账号自身Drive,需:
- 在Google Admin Console中为该服务账号启用域范围授权。
- 在代码中添加用户模拟逻辑,替换
user@your-domain.com为目标用户邮箱:GoogleCredentials credentials = GoogleCredentials.fromStream( new ByteArrayInputStream(authJson.getBytes())) .createScoped(SCOPES) .createDelegated("user@your-domain.com");
- 确认共享驱动器访问权限:若文件夹存储在共享驱动器中,需确保服务账号已被添加至该共享驱动器,且拥有相应权限。
内容的提问来源于stack exchange,提问作者slavkowski
相关产品推荐
相关产品推荐

