2014-04-17 79 views
3

我的項目是由Eclipse的GAE Plugin創建的(沒有Maven),我想要發佈我的代碼:將文件從HTML表單通過Servlet上傳到Google雲端存儲(使用Google雲端存儲客戶端庫for 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(); 
     } 
     } 

} 

我試圖也設定上傳的使用upload.setMaxSize(-1)的MAXIMUMSIZE;或將BUFFER_SIZE從2 * 1024 * 1024更改爲200 * 1024 * 1024,但問題仍然存在。更具體地講,當載達到100%,我收到此消息的網頁:

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

如何解決在使用JAVA和谷歌雲存儲客戶端庫的Java? (我不打算改變與其他編程語言的項目)

你能幫我找到解決方案嗎?非常感謝!

+0

什麼是文件的大小,你正在上傳。你可以嘗試一個小文件? – alex

+0

我嘗試過所有類型的大小,它似乎只適用於小於32MB的文件。我想上傳大於32MB的文件。 – Aerox

+0

請求大小限制爲32Mb。看到我的答案替代品。 – alex

回答

6

App Engine的請求限制爲32MB。這就是爲什麼當你發送一個大於32Mb的文件時,你的上傳失敗。 Checkout Quotas and Limits section

你有兩個選擇上傳文件> 32Mb的:

或者您也可以使用谷歌雲端硬盤,只存儲文檔的ID在數據存儲:)

+0

https://developers.google。com/storage /此鏈接和其他人不會談論Google Cloud Storage的請求限制,否則就沒有任何解決方案來執行上傳。我對嗎? – Aerox

+0

這不是雲存儲的限制,而是App Engine *的*請求限制。有關限制的更多詳細信息,請參閱以下網址:https://developers.google.com/appengine/docs/java/#Java_Quotas_and_limits – alex

+0

如果我要使用Blobstore,則會出現重複對象的問題(在Blobstore中和穀倉雲存儲內部)。正如「文檔」所述,您可以使用BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService(); BlobKey blobKey = blobstoreService.createGsBlobKey( 「/ gs /」+ fileName.getBucketName()+「/」+ fileName.getObjectName()); blobstoreService.serve(blobKey,resp);這不足以讓它工作。他們錯過了文檔示例中的所有代碼。請問你能幫幫我嗎? – Aerox

0

我會建議你看看這個很好的例子:http://docs.oracle.com/javaee/6/tutorial/doc/glraq.html 一個好主意是監視數據流到服務器。

希望它可以幫助

+1

如果你不知道你在寫什麼,我建議看看http://stackoverflow.com/questions/21406878/uploading-files-with-primefaces-4-0-and-jsf-2-2-谷歌應用程序引擎,因爲谷歌App Engine不支持Servlet 3.0。所以我非常感謝你以更具體的方式回答,因爲我已經測試了這個代碼3周,並且我有相當的文檔記錄。由於你發佈的代碼(我已經看到很多天),在我的情況下是無用的。您可以發佈Google App Engine的工作代碼嗎?非常感謝你。 – Aerox

相關問題