【问题标题】:Upload file from HTML form through Servlet to Google Cloud Storage (using Google Cloud Storage Client Library for Java)通过 Servlet 将 HTML 表单中的文件上传到 Google Cloud Storage(使用 Google Cloud Storage Client Library for Java)
【发布时间】:2014-06-02 08:53:46
【问题描述】:

我的项目是由 GAE Plugin for Eclipse(没有 Maven)创建的,我将发布我的代码:

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>

上传Servlet.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); 设置上传的最大尺寸;或将 BUFFER_SIZE 从 2*1024*1024 更改为 200*1024*1024,但问题仍然存在。更具体地说,当上传达到 100% 时,我在网页上收到此消息:

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

如何使用 JAVA 和 Google Cloud Storage Client Library for Java 解决这个问题? (我不会用其他编程语言彻底改变项目)

您能帮我找到解决方案吗?非常感谢!

【问题讨论】:

  • 您上传的文件的大小是多少。可以试试小文件吗?
  • 我尝试了各种大小,但它似乎只适用于小于 32MB 的文件。我想上传大于 32MB 的文件。
  • 请求大小限制为 32Mb。请参阅我的答案以获取替代方案。
  • 感谢您发布代码。这帮了我大忙!

标签: java html eclipse google-app-engine google-cloud-storage


【解决方案1】:

App Engine 请求限制为 32Mb。这就是当您发送大于 32Mb 的文件时上传失败的原因。 Checkout Quotas and Limits section.

您有两种上传文件的选项 > 32Mb:

或者您可以只使用 Google Drive 并在数据存储区中仅存储文档 ID :)

【讨论】:

  • developers.google.com/storage 这个链接和其他链接不讨论谷歌云存储的请求限制,否则将没有任何解决方案进行上传。我说的对吗?
  • 这不是 Cloud Storage 的限制,而是 对 App Engine 的请求的限制。有关您达到的限制的更多详细信息,请参阅此内容:developers.google.com/appengine/docs/java/…
  • @Aerox,我会看看今天晚些时候能否为您找到一些示例。我会告诉你的。
  • @Aerox 找不到最近的样本,所以我正在为您构建一个。应该很快就完成了。
  • @Aerox 这是示例应用程序:github.com/crhym3/java-blobstore-gcs-sample
【解决方案2】:

我建议你看看这个很棒的示例:http://docs.oracle.com/javaee/6/tutorial/doc/glraq.html 一个好主意是监控到服务器的数据流。

希望对你有帮助

【讨论】:

  • 如果你不知道自己在写什么,我建议你看看stackoverflow.com/questions/21406878/…,因为Google App Engine 不支持Servlet 3.0。因此,如果您能以更具体的方式回答,我真的很感激,因为我已经测试了这段代码 3 周,而且我已经得到了相当的记录。由于您发布的代码(我已经在很多天前看到过)在我的情况下是无用的。您能否发布 Google App Engine 的工作代码?非常感谢你。
猜你喜欢
  • 2015-08-28
  • 2017-04-07
  • 2018-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-31
  • 1970-01-01
  • 2017-08-11
相关资源
最近更新 更多