java - 通过 Servlet 将文件从 HTML 表单上传到 Google Cloud Storage(使用 Google Cloud Storage Client Library for Java)

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

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

首页.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 和适用于 Java 的 Google 云存储客户端库解决这个问题? (我不会用其他编程语言彻底改变项目)

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

最佳答案

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

上传文件 > 32Mb 有两种选择:

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

关于java - 通过 Servlet 将文件从 HTML 表单上传到 Google Cloud Storage(使用 Google Cloud Storage Client Library for Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23144082/

相关文章:

java - 如何从 SplittableRandom 获取 nextFloat() ?

java - 如何对包含 int+string 条目的数组列表进行数字排序

javascript - 如何使用jquery在弹出窗口中打开pdf文件

java - 警告:javax.persistence.spi::未找到有效的提供程序

java - 如何调试 "No Mapping found for HTTP Request"?

html - 如何向人造列侧边栏添加框阴影?

javascript - 显示与点击时生成的随机数对应的骰子元素

eclipse - 在 Eclipse 中设置深色主题会使功能工具提示不可读

java - 如何在Eclipse中为非Android Java项目使用Proguard?

android - 在 Eclipse 中每次构建后运行批处理文件