Cargar archivo desde el formulario HTML a través de Servlet a Google Cloud Storage (usando Google Cloud Storage Client Library para Java)

Mi proyecto ha sido creado por GAE Plugin para Eclipse (sin Maven) y voy a publicar mi código compuesto por:

home.jsp

   Upload Test   

UploadServlet.java:

 import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.nio.channels.Channels; import java.util.Enumeration; import java.util.logging.Logger; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItemIterator; import org.apache.commons.fileupload.FileItemStream; import org.apache.commons.fileupload.servlet.ServletFileUpload; import com.google.appengine.tools.cloudstorage.GcsFileOptions; import com.google.appengine.tools.cloudstorage.GcsFilename; import com.google.appengine.tools.cloudstorage.GcsOutputChannel; import com.google.appengine.tools.cloudstorage.GcsService; import com.google.appengine.tools.cloudstorage.GcsServiceFactory; import com.google.appengine.tools.cloudstorage.RetryParams; public class UploadServlet extends HttpServlet { private static final Logger log = Logger.getLogger(UploadServlet.class.getName()); private final GcsService gcsService = GcsServiceFactory.createGcsService(new RetryParams.Builder() .initialRetryDelayMillis(10) .retryMaxAttempts(10) .totalRetryPeriodMillis(15000) .build()); private String bucketName = "myBucketNameOnGoogleCloudStorage"; /**Used below to determine the size of chucks to read in. Should be > 1kb and < 10MB */ private static final int BUFFER_SIZE = 2 * 1024 * 1024; @SuppressWarnings("unchecked") @Override public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String sctype = null, sfieldname, sname = null; ServletFileUpload upload; FileItemIterator iterator; FileItemStream item; InputStream stream = null; try { upload = new ServletFileUpload(); res.setContentType("text/plain"); iterator = upload.getItemIterator(req); while (iterator.hasNext()) { item = iterator.next(); stream = item.openStream(); if (item.isFormField()) { log.warning("Got a form field: " + item.getFieldName()); } else { log.warning("Got an uploaded file: " + item.getFieldName() + ", name = " + item.getName()); sfieldname = item.getFieldName(); sname = item.getName(); sctype = item.getContentType(); GcsFilename gcsfileName = new GcsFilename(bucketName, sname); GcsFileOptions options = new GcsFileOptions.Builder() .acl("public-read").mimeType(sctype).build(); GcsOutputChannel outputChannel = gcsService.createOrReplace(gcsfileName, options); copy(stream, Channels.newOutputStream(outputChannel)); res.sendRedirect("/"); } } } catch (Exception ex) { throw new ServletException(ex); } } private void copy(InputStream input, OutputStream output) throws IOException { try { byte[] buffer = new byte[BUFFER_SIZE]; int bytesRead = input.read(buffer); while (bytesRead != -1) { output.write(buffer, 0, bytesRead); bytesRead = input.read(buffer); } } finally { input.close(); output.close(); } } } 

Intenté también establecer el máximo tamaño de la carga usando upload.setMaxSize (-1); o cambiando el BUFFER_SIZE de 2 * 1024 * 1024 a 200 * 1024 * 1024, pero el problema persiste. Para ser más específico, cuando la carga llega al 100%, recibo este mensaje en la página web:

 Error: Request Entity Too Large Your client issued a request that was too large. 

¿Cómo puedo solucionar eso usando JAVA y Google Cloud Storage Client Library para Java? (No voy a cambiar drásticamente el proyecto con otros lenguajes de progtwigción)

¿Podría ayudarme a encontrar una solución? Muchas gracias!

El límite de solicitud de App Engine es de 32Mb. Es por eso que tus cargas fallan cuando envías un archivo> 32Mb. Sección de Cuotas y Límites de Checkout .

Tienes dos opciones para subir archivos> 32Mb:

  • API de Blobstore . Puede especificar un segmento de GCS en lugar de usar el espacio de almacenamiento de Blobstore.

    Para hacer eso, use el createUploadUrl(java.lang.String successPath, UploadOptions uploadOptions) de BlobstoreService .

    Aquí hay una aplicación de ejemplo: https://github.com/crhym3/java-blobstore-gcs-sample

  • Característica de URL firmadas de GCS

O simplemente puede usar Google Drive y almacenar solo documentos de identidad de documentos en el almacén de datos 🙂

Le sugiero que eche un vistazo a este excelente ejemplo de ejemplo: http://docs.oracle.com/javaee/6/tutorial/doc/glraq.html. Una buena idea será monitorear el flujo de datos al servidor.

Espero eso ayude