通过 Servlet 将 HTML 表单中的文件上传到 Google Cloud Storage(使用 Google Cloud Storage Client Library for Java)
我的项目是由 GAE Plugin for Eclipse(没有 Maven)创建的,我将发布我的代码:
My project has been created by GAE Plugin for Eclipse (without Maven) and i'm goint to post my code composed by:
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:
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); 设置上传的最大尺寸;或将 BUFFER_SIZE 从 2*1024*1024 更改为 200*1024*1024,但问题仍然存在.更具体地说,当上传达到 100% 时,我在网页上收到此消息:
I tried also to set the maximumSize of the Upload using upload.setMaxSize(-1); or changing the BUFFER_SIZE from 2*1024*1024 into 200*1024*1024, but the issue stil occur. To be more specific, when the uploading reach the 100% I receive this message on the webpage:
Error: Request Entity Too Large Your client issued a request that was too large.
如何使用 JAVA 和 Google Cloud Storage Client Library for Java 解决这个问题?(我不会用其他编程语言彻底改变项目)
How can i fix that using JAVA and Google Cloud Storage Client Library for Java? (I'm not going to change drastically the Project with other Programming Languages)
您能帮我找到解决方案吗?非常感谢!
Could you please help me to find a solution? Thank you so much!
推荐答案
App Engine 请求限制为 32Mb.这就是当您发送大于 32Mb 的文件时上传失败的原因.签出配额和限制部分.
App Engine request limit is 32Mb. That's why your uploads are failing when you send a file > 32Mb. Checkout Quotas and Limits section.
您有两种上传文件的选项 > 32Mb:
You have two options for uploading files > 32Mb:
Blobstore API.您可以指定 GCS 存储桶而不是使用 Blobstore 存储空间.
Blobstore API. You can specify a GCS bucket instead of using Blobstore storage space.
为此,请使用 BlobstoreService
的 createUploadUrl(java.lang.String successPath, UploadOptions uploadOptions)
方法.
To do that use createUploadUrl(java.lang.String successPath, UploadOptions uploadOptions)
method of BlobstoreService
.
这是一个示例应用程序:https://github.com/crhym3/java-blobstore-gcs-sample
Here's a sample app: https://github.com/crhym3/java-blobstore-gcs-sample
GCS 的签名 URL 功能
或者您可以只使用 Google Drive 并在数据存储区中仅存储文档 ID :)
Or you could just use Google Drive and store only doc IDs in the datastore :)
相关文章