Java 无法更新appdata作用域中的文件存储-500内部服务器错误

Java 无法更新appdata作用域中的文件存储-500内部服务器错误,java,google-drive-api,Java,Google Drive Api,在此之前,我有一组GoogleDrive API代码,在以下场景中运行良好 将新文件保存到appdata 更新appdata中以前的文件 将新文件保存到非appdata 在非appdata中更新以前的文件 几天前,我遇到场景2不再工作(更新appdata中以前的文件),而其他场景仍然可以正常工作。我将得到以下异常 com.google.api.client.googleapis.json.GoogleJsonResponseException: 500 Internal Server Error

在此之前,我有一组GoogleDrive API代码,在以下场景中运行良好

  • 将新文件保存到appdata
  • 更新appdata中以前的文件
  • 将新文件保存到非appdata
  • 在非appdata中更新以前的文件
  • 几天前,我遇到场景2不再工作(更新appdata中以前的文件),而其他场景仍然可以正常工作。我将得到以下异常

    com.google.api.client.googleapis.json.GoogleJsonResponseException: 500 Internal Server Error
    {
      "code": 500,
      "errors": [
        {
          "domain": "global",
          "message": "Internal Error",
          "reason": "internalError"
        }
      ],
      "message": "Internal Error"
    }
        at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
        at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
        at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
        at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:423)
        at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
        at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
        at org.yccheok.jstock.gui.Utils.updateFile(Utils.java:1414)
    
    我使用的是
    驱动器
    驱动器应用数据
    范围-

    代码如下

    • 在更新文件期间不起作用。在保存新文件期间工作
    • ,一切顺利
    在第1414行抛出异常,这是

    com.google.api.services.drive.model.File updatedFile = service.files().update(fileId, file, mediaContent).setNewRevision(false).execute();
    
    使用query
    title在appdata中搜索上一个文件时,包含“jstock-fe78440e-e0fe-4efb”和trashed=false,在parents中搜索“appdata”是完全正确的。我们能够毫无问题地检索以前的文件id

    但是,当我们使用检索到的文件id执行文件更新时,将抛出
    500内部服务器错误

    某些用户在搜索appdata时遇到问题(我的情况不是这样)。建议的解决方法是添加
    drive.readonly.metadata
    。我试过一次,但没什么区别


    更新 由

    我设法重现了这个问题。如果不使用setNewRevision(false),则为 工作-我意识到这可能不是在所有情况下都可行,但它是一个 目前对你来说是合理的解决办法吗

    不过,目前我将暂缓此类解决方案。我们希望使用
    setNewRevision(false)
    ,以防止增加用户数据存储配额的使用-


    演示问题的简短而完整的源代码

  • 创建客户端id和密钥。更新源代码
  • 创建
    document.txt
  • 第一次运行源代码,将
    document.txt
    上传到
    appdata
    文件夹。它应该成功。通过在线谷歌硬盘查看上传的文件。(请参阅附件)
  • 第二次运行源代码,对
    appdata
    文件夹中以前的
    document.txt
    执行更新。应引发
    500内部服务器错误
    异常
  • /*
    *要更改此许可证标题,请在“项目属性”中选择“许可证标题”。
    *要更改此模板文件,请选择工具|模板
    *然后在编辑器中打开模板。
    */
    包装插页;
    导入com.google.api.client.auth.oauth2.Credential;
    导入com.google.api.client.googleapis.auth.oauth2.googleaauthorizationcodeflow;
    导入com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
    导入com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
    导入com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
    导入com.google.api.client.http.FileContent;
    导入com.google.api.client.http.HttpTransport;
    导入com.google.api.client.json.gson.GsonFactory;
    导入com.google.api.services.drive.drive;
    导入com.google.api.services.drive.DriveScopes;
    导入com.google.api.services.drive.model.FileList;
    导入com.google.api.services.drive.model.ParentReference;
    导入java.io.BufferedReader;
    导入java.io.IOException;
    导入java.io.InputStreamReader;
    导入java.security.GeneralSecurityException;
    导入java.util.array;
    导入org.apache.commons.logging.Log;
    导入org.apache.commons.logging.LogFactory;
    公共类插入{
    私有静态com.google.api.services.drive.model.filesearchfromGoogleDrive(驱动器驱动器,字符串qString){
    试一试{
    Drive.Files.List请求=Drive.Files().List().setQ(qString);
    做{
    FileList FileList=request.execute();
    com.google.api.services.drive.model.File文件=null;
    对于(com.google.api.services.drive.model.f:fileList.getItems()){
    最终字符串标题=f.getTitle();
    if(title==null | | f.getDownloadUrl()==null | | f.getDownloadUrl().length()0);
    }捕获(IOEX异常){
    log.error(null,ex);
    返回null;
    }
    返回null;
    }
    公共静态布尔SaveToLogleDrive(凭证凭证凭证,java.io.File文件){
    最终字符串titleName=“document.txt”;
    最后一个字符串qString=“title包含”“+titleName+”,并在父级中包含trashed=false和“appdata”;
    返回_savetologledrive(凭证、文件、qString,“appdata”);
    }
    公共静态驱动器getDrive(凭据){
    驱动器服务=new Drive.Builder(httpTransport,JSON_工厂,凭证).setApplicationName(“JStock”).build();
    回程服务;
    }
    私有静态布尔值_savetogologledrive(凭证凭证、java.io.File文件、字符串qString、字符串文件夹){
    驱动器=getDrive(凭证);
    //我们应该换新的还是换新的?
    com.google.api.services.drive.model.File googleCloudFile=searchFromGoogleDrive(驱动器,qString);
    最终字符串title=“document.txt”;
    if(googleCloudFile==null){
    字符串id=null;
    如果(文件夹!=null){
    com.google.api.services.drive.model.File appData;
    试一试{
    appData=drive.files().get(folder.execute();
    id=appData.getId();
    }捕获(IOEX异常){
    log.error(null,ex);
    返回false;
    }
    }
    返回null!=插入文件(驱动器、标题、id、文件);
    }否则{
    final com.google.api.services.drive.model.File oldFile=googleCloudFile;
    返回null!=updateFile(驱动器,oldFile.getId())
    
    /*
     * To change this license header, choose License Headers in Project Properties.
     * To change this template file, choose Tools | Templates
     * and open the template in the editor.
     */
    
    package insert;
    
    import com.google.api.client.auth.oauth2.Credential;
    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.googleapis.javanet.GoogleNetHttpTransport;
    import com.google.api.client.http.FileContent;
    import com.google.api.client.http.HttpTransport;
    import com.google.api.client.json.gson.GsonFactory;
    import com.google.api.services.drive.Drive;
    import com.google.api.services.drive.DriveScopes;
    import com.google.api.services.drive.model.FileList;
    import com.google.api.services.drive.model.ParentReference;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.security.GeneralSecurityException;
    import java.util.Arrays;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    
    
    public class Insert {
    
        private static com.google.api.services.drive.model.File searchFromGoogleDrive(Drive drive, String qString) {
            try {
                Drive.Files.List request = drive.files().list().setQ(qString);
    
                do {                
                    FileList fileList = request.execute();
    
                    com.google.api.services.drive.model.File file = null;
    
                    for (com.google.api.services.drive.model.File f : fileList.getItems()) {
    
                        final String title = f.getTitle();
    
                        if (title == null || f.getDownloadUrl() == null || f.getDownloadUrl().length() <= 0) {
                            continue;
                        }
    
                        file = f;
    
                        break;
                    }
    
                    if (file != null) {
                        return file;
                    }
    
                    request.setPageToken(fileList.getNextPageToken());
                } while (request.getPageToken() != null && request.getPageToken().length() > 0);
            } catch (IOException ex) {
                log.error(null, ex);
                return null;
            }
            return null;
        }
    
        public static boolean saveToGoogleDrive(Credential credential, java.io.File file) {
            final String titleName = "document.txt";
            final String qString = "title contains '" + titleName + "' and trashed = false and 'appdata' in parents";        
            return _saveToGoogleDrive(credential, file, qString, "appdata");
        }
    
        public static Drive getDrive(Credential credential) {
            Drive service = new Drive.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName("JStock").build();
            return service;
        }
    
        private static boolean _saveToGoogleDrive(Credential credential, java.io.File file, String qString, String folder) {
            Drive drive = getDrive(credential);
    
            // Should we new or replace?
    
            com.google.api.services.drive.model.File googleCloudFile = searchFromGoogleDrive(drive, qString);
    
            final String title = "document.txt";
    
            if (googleCloudFile == null) {
                String id = null;
                if (folder != null) {
                    com.google.api.services.drive.model.File appData;
                    try {
                        appData = drive.files().get(folder).execute();
                        id = appData.getId();
                    } catch (IOException ex) {
                        log.error(null, ex);
                        return false;
                    }
                }
                return null != insertFile(drive, title, id, file);
            } else {
                final com.google.api.services.drive.model.File oldFile = googleCloudFile;
                return null != updateFile(drive, oldFile.getId(), title, file);
            }
        }
    
        /**
         * Insert new file.
         *
         * @param service Drive API service instance.
         * @param title Title of the file to insert, including the extension.
         * @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 com.google.api.services.drive.model.File insertFile(Drive service, String title, String parentId, java.io.File fileContent) {
            // File's metadata.
            com.google.api.services.drive.model.File body = new com.google.api.services.drive.model.File();
            body.setTitle(title);
    
            // Set the parent folder.
            if (parentId != null && parentId.length() > 0) {
                body.setParents(
                    Arrays.asList(new ParentReference().setId(parentId)));
            }
    
            // File's content.
            FileContent mediaContent = new FileContent("", fileContent);
            try {
                com.google.api.services.drive.model.File file = service.files().insert(body, mediaContent).execute();
                return file;
            } catch (IOException e) {
                log.error(null, e);
                return null;
            }
        }
    
        /**
         * Update an existing file's metadata and content.
         *
         * @param service Drive API service instance.
         * @param fileId ID of the file to update.
         * @param newTitle New title for the file.
         * @param newFilename Filename of the new content to upload.
         * @return Updated file metadata if successful, {@code null} otherwise.
         */
        private static com.google.api.services.drive.model.File updateFile(Drive service, String fileId, String newTitle, java.io.File fileContent) {
            try {
                // First retrieve the file from the API.
                com.google.api.services.drive.model.File file = service.files().get(fileId).execute();
    
                // File's new metadata.
                file.setTitle(newTitle);
    
                FileContent mediaContent = new FileContent("", fileContent);
    
                // Send the request to the API.
                com.google.api.services.drive.model.File updatedFile = service.files().update(fileId, file, mediaContent).setNewRevision(false).execute();
    
                return updatedFile;
            } catch (IOException e) {
                log.error(null, e);
                return null;
            }
        }
    
      private static String CLIENT_ID = "CLIENT_ID";
      private static String CLIENT_SECRET = "CLIENT_SECRET";
    
      private static String REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
    
      public static void main(String[] args) throws IOException {   
        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
            httpTransport, JSON_FACTORY, CLIENT_ID, CLIENT_SECRET, Arrays.asList(DriveScopes.DRIVE_APPDATA, DriveScopes.DRIVE))
            .setAccessType("online")
            .setApprovalPrompt("auto").build();
    
        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);
    
        java.io.File fileContent = new java.io.File("document.txt");
        saveToGoogleDrive(credential, fileContent);
      }
    
        private static final GsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
    
        /** Global instance of the HTTP transport. */
        private static HttpTransport httpTransport;
    
    
        private static final Log log = LogFactory.getLog(Insert.class);
    
        static {
            try {
                // initialize the transport
                httpTransport = GoogleNetHttpTransport.newTrustedTransport();
    
            } catch (IOException ex) {
                log.error(null, ex);
            } catch (GeneralSecurityException ex) {
                log.error(null, ex);
            }
        }
    
    }
    
    setNewRevision(false)