2014-04-17 4 views
3

Mon projet a été créé par GAE Plugin pour Eclipse (sans Maven) et je dois publier mon code composé de:Télécharger un fichier depuis un formulaire HTML via Servlet vers Google Cloud Storage (en utilisant la bibliothèque client Google Cloud Storage pour Java)

home.jsp

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
    <head> 
    <title>Upload Test</title> 
    </head> 
    <body> 
     <form action="/upload" method="post" name="putFile" id="putFile" 
       enctype="multipart/form-data"> 
       <input type="file" name="myFile" id="fileName"> 
       <input type="submit" value="Upload"> 
     </form> 
    </body> 
    </html> 

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(); 
     } 
     } 

} 

I a essayé également de régler la maximumSize du chargement en utilisant upload.setMaxSize (-1); ou en changeant le BUFFER_SIZE de 2 * 1024 * 1024 en 200 * 1024 * 1024, mais le problème persiste. Pour être plus précis, lorsque le chargement atteint 100% que je reçois ce message sur la page Web:

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

Comment puis-je résoudre ce problème en utilisant JAVA et Google Cloud Storage Library pour Java client? (Je ne vais pas changer radicalement le projet avec d'autres langages de programmation)

Pourriez-vous s'il vous plaît m'aider à trouver une solution? Merci beaucoup!

+0

Quelle est la taille du fichier 're télécharger. Pouvez-vous essayer avec un petit fichier? – alex

+0

J'ai essayé avec toutes sortes de taille, et il semble fonctionner uniquement avec des fichiers de moins de 32 Mo. Je voudrais télécharger des fichiers supérieurs à 32 Mo. – Aerox

+0

la taille limite de la demande est de 32Mb. voir ma réponse pour des alternatives. – alex

Répondre

6

La limite de demande App Engine est de 32 Mo. C'est pourquoi vos téléchargements échouent lorsque vous envoyez un fichier> 32 Mo. Checkout Quotas and Limits section.

Vous avez deux options pour le téléchargement de fichiers> 32Mb:

Ou vous pouvez simplement utiliser Google Drive et stocker uniquement ID doc dans le datastore :)

+0

https://developers.google.com/storage/Ce lien et d'autres ne parlent pas de la limite de requêtes pour Google Cloud Storage, sinon il n'y aurait pas de solution pour faire un Upload. Ai-je raison? – Aerox

+0

Il ne s'agit pas d'une limite de Cloud Storage mais de la limite d'une requête * vers App Engine *. Voir ce pour plus de détails sur la limite que vous touchez: https://developers.google.com/appengine/docs/java/#Java_Quotas_and_limits – alex

+0

Si je vais utiliser Blobstore il y aurait des problèmes d'objets en double (en Blobstore et Google Cloud Storage dans des compartiments). Comme le dit la "documentation", vous pouvez utiliser BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService(); BlobKey blobKey = blobstoreService.createGsBlobKey ( "/ gs /" + fileName.getBucketName() + "/" + fileName.getObjectName()); blobstoreService.serve (blobKey, resp); Ce n'est pas suffisant pour le laisser fonctionner. Ils manquent tout le code dans l'exemple de documentation. Pourrais-tu m'aider s'il te plait? – Aerox

0

Je vais vous suggérer de jeter un coup d'œil à cet excellent exemple: http://docs.oracle.com/javaee/6/tutorial/doc/glraq.html Une bonne idée sera de surveiller le flux de données vers le serveur.

Espérons que cela aide

+1

Si vous ne savez pas ce que vous écrivez, je suggère de jeter un oeil à http://stackoverflow.com/questions/21406878/uploading-files-with-primefaces-4-0-and-jsf-2-2- moteur d'application Google, car Google App Engine ne prend pas en charge Servlet 3.0. Donc j'apprécie vraiment que vous répondiez d'une manière plus spécifique, parce que j'ai testé ce code pendant 3 semaines et que je suis assez documenté. Puisque le code que vous avez posté (que j'ai déjà vu il y a plusieurs jours) est inutile dans mon cas. Pourriez-vous poster un code de travail pour Google App Engine, s'il vous plaît? Merci beaucoup l'homme. – Aerox

Questions connexes