java - vaya - todavia se esta cargando google drive
No se puede actualizar el almacén de archivos en el ámbito de datos de aplicaciones-500 Error interno del servidor (1)
Anteriormente, tengo un conjunto de código de API de Google Drive, que funciona bien en los siguientes escenarios
- Guardar nuevo archivo en appdata
- Actualizar el archivo anterior en appdata
- Guardar archivo nuevo en datos no appdata
- Actualizar el archivo anterior en datos no appdata
Hace unos días, me encuentro con que el escenario 2 ya no funciona (Actualizar el archivo anterior en appdata), mientras que otros escenarios aún funcionan sin problemas. Obtendré la siguiente excepción.
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)
Estoy usando el alcance DRIVE
y DRIVE_APPDATA
- authorizeDrive()
El código es el siguiente.
- saveToGoogleDrive (): guardar o actualizar el archivo en appdata , no funciona durante la actualización del archivo . Trabajar durante guardar nuevo archivo.
- saveToLegacyGoogleDrive () - ¡Guardar o actualizar el archivo en datos que no sean appdata , todo funciona!
Se está lanzando una excepción en la línea 1414, que es
com.google.api.services.drive.model.File updatedFile = service.files().update(fileId, file, mediaContent).setNewRevision(false).execute();
Buscar en el archivo anterior en appdata usando el title contains ''jstock-fe78440e-e0fe-4efb'' and trashed = false and ''appdata'' in parents
consulta title contains ''jstock-fe78440e-e0fe-4efb'' and trashed = false and ''appdata'' in parents
está completamente bien. Podemos recuperar la identificación del archivo anterior sin problema.
Sin embargo, se produce 500 Internal Server Error
cuando realizamos la actualización de archivos utilizando la ID de archivo recuperada.
Algunos usuarios encontraron problemas durante la búsqueda en appdata (que no es mi caso). Busque en la carpeta ''appdata'' La solución sugerida es agregar drive.readonly.metadata
. Lo había intentado una vez, pero no hay diferencia.
Actualizar
Una excelente solución propuesta por Jon Skeet
He logrado reproducir el problema. Sin setNewRevision (falso) funciona, me doy cuenta de que puede no ser viable en todos los casos, pero ¿es una solución razonable para usted por el momento?
Sin embargo, en espera de tal solución en este momento. Preferimos tener setNewRevision(false)
, para evitar que se incremente el uso de la cuota de almacenamiento de datos del usuario: http://developers.google.com/drive/v2/reference/files/update
Código fuente corto pero completo para demostrar el problema.
- Crear un ID de cliente y clave secreta. Actualizar el código fuente.
- Crear un
document.txt
- Ejecute el código fuente por primera vez , para cargar
document.txt
en la carpetaappdata
. Debería tener éxito. Compruebe su archivo cargado a través de Google Drive en línea. (Por favor vea el adjunto) - Ejecute el código fuente por segunda vez , para realizar la actualización en el
document.txt
anterior en la carpetaappdata
. Se debe lanzar la excepción500 Internal Server Error
.
/*
* 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);
}
}
}
Actualización el 1 de enero de 2016
Este problema parece haberse ido. Supongo que el equipo de Google Drive lo había arreglado.
Nota: no trate esto como una "respuesta oficial de Google". Aunque trabajo en Google, no trabajo en la API de Drive.
He reproducido el problema y lo he informado al equipo de Drive API, que puede proporcionar más detalles. Mientras tanto, una solución que he encontrado es eliminar el
setNewRevision(false)
parte de su llamada de update
en la línea 1414. Esa no es una solución ideal, ya que significa que obtendrá una nueva revisión para cada actualización, que utilizará la cuota de almacenamiento. Sin embargo, parece evitar el problema que has visto.