无法在appdata作用域中更新文件存储 - 500内部服务器错误 [英] Unable update file store in appdata scope - 500 Internal Server Error

查看:95
本文介绍了无法在appdata作用域中更新文件存储 - 500内部服务器错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以前,我有一组Google Drive API代码,在以下情况下可以正常工作


  1. 将新文件保存到appdata

  2. 在appdata中更新以前的文件

  3. 将新文件保存为非appdata
  4. >更新非appdata中的前一个文件

几天前,我遇到方案2不再工作(更新appdata中的前一个文件),而其他场景仍然没有问题。

  com.google.api.client.googleapis.json.GoogleJsonResponseException:500内部服务器错误
{
code:500,
errors:[
{
domain:global,
message:内部错误,
reason:internalError
}
],
message:内部错误
}
at com。 google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
,位于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)
,位于com.google.api.client.googleapis.se rvices.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
,位于com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
位于org.yccheok.jstock。我使用<$ c $() c> DRIVE
DRIVE_APPDATA 范围 - authorizeDrive()



代码如下




  • saveToGoogleDrive() - 保存或更新appdata中的文件在更新文件期间不起作用。在保存新文件期间工作。

  • saveToLegacyGoogleDrive() - 保存或更新非appdata中的文件,所有作品都是有效的!



  • 第1414行引发异常,这是

      com.google.api.services.drive.model。 File updatedFile = service.files()。update(fileId,file,mediaContent).setNewRevision(false).execute(); 

    使用查询标题在appdata中搜索以前的文件包含'jstock-fe78440e-e0fe -4efb',并且trashed = false和'appdata'在父母中完全没问题。我们可以毫无问题地检索以前的文件ID。然而,当我们使用检索到的文件ID执行文件更新时,正在抛出 500内部服务器错误

    p>

    有些用户在appdata搜索过程中遇到问题(这不是我的情况)。 'appdata'文件夹内的搜索文件夹建议的解决方法是添加 drive.readonly.metadata 。我已经尝试了一次,但没有区别。




    更新



    Jon Skeet 提出的极佳解决方法



    < blockquote>

    我设法重现了这个问题。没有setNewRevision(false)它
    的作品 - 我意识到这可能在所有情况下都不可行,但对于你来说这是一个
    合理的解决方法吗?




    但是,我现在将暂时搁置这种解决方法。我们倾向于使用 setNewRevision(false),以防止导致用户数据存储配额的使用增加 - http://developers.google.com/drive/v2/reference/files/update






    显示问题的简短但完整的源代码


    1. 创建客户端ID&密钥。更新源代码。
    2. 创建一个 document.txt

    3. 运行源代码第一次,上传 document.txt appdata 文件夹。它应该成功。通过在线Google云端硬盘检查您上传的文件。 (请参阅附件)

    4. 运行第二次的源代码,对之前的 document.txt执行更新放在 appdata 文件夹中。应抛出 500内部服务器错误异常。

      / * 
    *要更改此许可证标题,请在项目属性中选择许可证标题。
    *要更改此模板文件,请选择工具|模板
    *并在编辑器中打开模板。
    * /

    包装说明;

    import com.google.api.client.auth.oauth2.Credential;
    import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
    导入com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
    导入com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
    导入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;
    导入com.google.api.services.drive.Drive;
    导入com.google.api.services.drive.DriveScopes;
    导入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;


    公共类插入{

    私有静态com.google.api.services.drive.model.File searchFromGoogleDrive(驱动器驱动器,字符串qString){
    尝试{
    Drive.Files.List request = drive.files()。list()。setQ(qString);

    do {
    FileList fileList = request.execute();

    com.google.api.services.drive.model.File file = null; (com.google.api.services.drive.model.File f:fileList.getItems()){

    最终字符串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()); (request.getPageToken()!= null&&&& amp; request.getPageToken()。length()> 0);
    }
    } catch(IOException ex){
    log.error(null,ex);
    返回null;
    }
    返回null;
    }

    public static boolean saveToGoogleDrive(凭证凭证,java.io.File文件){
    final String titleName =document.txt;
    final String qString =title contains'+ titleName +'和trashed = false以及父母中的'appdata';
    返回_saveToGoogleDrive(凭证,文件,qString,appdata);
    }

    public static Drive getDrive(Credential credential){
    Drive service = new Drive.Builder(httpTransport,JSON_FACTORY,credential).setApplicationName(JStock)。build );
    退货服务;
    }

    private static boolean _saveToGoogleDrive(凭证凭证,java.io.File文件,字符串qString,字符串文件夹){
    Drive drive = getDrive(credential);

    //我们应该新建还是替换?

    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;
    尝试{
    appData = drive.files()。get(folder).execute();
    id = appData.getId();
    } catch(IOException ex){
    log.error(null,ex);
    返回false;
    }
    }
    返回null!= insertFile(drive,title,id,file);
    } else {
    final com.google.api.services.drive.model.File oldFile = googleCloudFile;
    返回null!= updateFile(drive,oldFile.getId(),title,file);
    }
    }

    / **
    *插入新文件。
    *
    * @param服务Drive API服务实例。
    * @param title要插入的文件的标题,包括扩展名。
    * @param parentId可选父文件夹的ID。
    * @param mimeType要插入的文件的MIME类型。
    * @param filename要插入的文件的文件名。
    * @return成功时插入文件元数据,否则返回{@code null}。
    * /
    private static com.google.api.services.drive.model.File insertFile(Drive service,String title,String parentId,java.io.File fileContent){
    //文件的元数据。
    com.google.api.services.drive.model.File body = new com.google.api.services.drive.model.File();
    body.setTitle(title);

    //设置父文件夹。
    if(parentId!= null&& parentId.length()> 0){
    body.setParents(
    Arrays.asList(new ParentReference().setId(parentId)) );
    }

    //文件内容。
    FileContent mediaContent = new FileContent(,fileContent);
    尝试{
    com.google.api.services.drive.model.File file = service.files()。insert(body,mediaContent).execute();
    返回文件;
    } catch(IOException e){
    log.error(null,e);
    返回null;
    }
    }

    / **
    *更新现有文件的元数据和内容。
    *
    * @param服务Drive API服务实例。
    * @param fileId要更新的文件的ID。
    * @param newTitle文件的新标题。
    * @param newFilename要上传的新内容的文件名。
    * @return如果成功则更新文件元数据,否则返回{@code null}。
    * /
    private static com.google.api.services.drive.model.File updateFile(Drive service,String fileId,String newTitle,java.io.File fileContent){
    try {
    //首先从API中检索文件。
    com.google.api.services.drive.model.File file = service.files()。get(fileId).execute();

    //文件的新元数据。
    file.setTitle(newTitle);

    FileContent mediaContent = new FileContent(,fileContent);

    //将请求发送到API。
    com.google.api.services.drive.model.File updatedFile = service.files()。update(fileId,file,mediaContent).setNewRevision(false).execute();

    返回updatedFile;
    } catch(IOException e){
    log.error(null,e);
    返回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(请在浏览器中打开以下URL,然后输入授权码:);
    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凭证=新的GoogleCredential()。setFromTokenResponse(response);

    java.io.File fileContent = new java.io.File(document.txt);
    saveToGoogleDrive(凭证,fileContent);
    }

    private static final GsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();

    / ** HTTP传输的全局实例。 * /
    私人静态HttpTransport httpTransport;


    private static final Log log = LogFactory.getLog(Insert.class);

    static {
    try {
    //初始化传输
    httpTransport = GoogleNetHttpTransport.newTrustedTransport();

    } catch(IOException ex){
    log.error(null,ex);
    } catch(GeneralSecurityException ex){
    log.error(null,ex);
    }
    }

    }



    2016年1月1日



    这个问题似乎没有了。我猜Google Drive团队已经解决了它。

    虽然我在谷歌工作,但我并没有在Drive API上工作。



    我重现了这个问题,并将它报告给了Drive API小组,他们可能能够提供更多细节。与此同时,我找到的一个解决方法是删除

      setNewRevision(false)

    是你的更新在第1414行上的一部分。这不是一个理想的解决方法意味着您将获得每次更新的新版本,这将会占用存储配额。但是,它似乎避免了你见过的问题。


    Previously, I have a set of Google Drive API code, which works fine in the following scenarios

    1. Save new file to appdata
    2. Update previous file in appdata
    3. Save new file to non-appdata
    4. Update previous file in non-appdata

    Few days ago, I encounter scenario 2 no longer work (Update previous file in appdata), whereas other scenarios still work without problem. I will be getting the following exception.

    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)
    

    I'm using both DRIVE and DRIVE_APPDATA scope - authorizeDrive()

    The code is as follow

    Exception is being thrown at Line 1414, which is

    com.google.api.services.drive.model.File updatedFile = service.files().update(fileId, file, mediaContent).setNewRevision(false).execute();
    

    Searching previous file in appdata using query title contains 'jstock-fe78440e-e0fe-4efb' and trashed = false and 'appdata' in parents is completely fine. We're able to retrieve the previous file id without problem.

    However, 500 Internal Server Error is being thrown, when we perform file updating using retrieved file id.

    Some users encountered problem during searching in appdata (which is not my case). Search folder inside 'appdata' folder The suggested workaround is to add drive.readonly.metadata. I had tried that once, but it makes no difference.


    Update

    An excellent workaround proposed by Jon Skeet

    I've managed to reproduce the issue. Without setNewRevision(false) it works - I realize that may not be feasible in all cases, but is it a reasonable workaround for you for the moment?

    However, I will on hold on such workaround at this moment. We prefer to have setNewRevision(false), to prevent from causing increased use of the user's data storage quota - http://developers.google.com/drive/v2/reference/files/update


    Short but complete source code to demonstrate the problem

    1. Create a client id & secret key. Update source code.
    2. Create a document.txt
    3. Run the source code first time, to upload document.txt to appdata folder. It should success. Check your uploaded file through online Google Drive. (Please refer to attachment)
    4. Run the source code for second time, to perform update on previous document.txt in appdata folder. The 500 Internal Server Error exception should be thrown.

    /*
     * 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);
            }
        }
    
    }
    

    Update on 1 January 2016

    This problem seems gone. I guess Google Drive team had fixed it.

    解决方案

    Note: please do not treat this as an "official answer from Google". Although I work at Google, I don't work on the Drive API.

    I've reproduced the problem, and reported it to the Drive API team, who may be able to provide more details. In the meantime, one workaround I've found is to remove the

    setNewRevision(false)
    

    part of your update call on line 1414. That's not an ideal workaround as it means you'll get a new revision for each update, which will use up storage quota. However, it does seem to avoid the problem you've seen.

    这篇关于无法在appdata作用域中更新文件存储 - 500内部服务器错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆