在这个答案的帮助下,我终于想通了。
首先,确保在您的 appengine-web.xml 中启用了会话:<sessions-enabled>true</sessions-enabled>
我最终编写了两个单独的 servlet,一个创建上传 URL,第二个在图像写入 blobstore 后处理重定向。
图片上传 URL servlet
public void doGet(HttpServletRequest pRequest, HttpServletResponse pResponse) throws IOException {
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
Map<String, String> payload = new HashMap<String, String>();
payload.put("url", blobstoreService.createUploadUrl("/imageUpload"));
LOGGER.info("Payload: " + GSON.toJson(payload));
pResponse.setContentType("application/json");
pResponse.getWriter().println(GSON.toJson(payload));
}
客户端图片上传请求者
// request function
...
goog.net.XhrIo.send('/imageUploadURL', goog.bind(this.handleURLReceived, this));
...
// response handler function
myapp.ImageDrop.prototype.handleURLReceived = function(event)
{
this.postURL = this.extractValidJson(event).url;
myapp.logger.fine('Response: ' + this.postURL);
};
extractValidJson(event)
只是我编写的用于提取 json 响应的实用程序函数。
一旦我们有了一个有效的 URL,我们就可以允许上传。
客户端上传丢弃发件人
// In constructor
...
var dropZone = goog.dom.getElement('image-drop');
var handler = new goog.events.FileDropHandler(dropZone, true);
goog.events.listen(handler, goog.events.FileDropHandler.EventType.DROP, goog.bind(this.handleDrop, this));
...
// FileDropHandler
myapp.ImageDrop.prototype.handleDrop = function(event)
{
var files = event.getBrowserEvent().dataTransfer.files;
var file = files[0]; // IRL, do error checking
this.xhr = new goog.net.XmlHttp();
this.xhr.open('POST', this.postURL, true); // asych
this.xhr.onreadystatechange = goog.bind(this.uploadResponseHandler, this);
var form_data = new FormData();
form_data.append('file', file); // name is arbitrary, must match in servlet
this.xhr.send(form_data);
};
图片上传重定向 servlet
public void doPost(HttpServletRequest pRequest, HttpServletResponse pResponse) throws IOException {
Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(pRequest);
// 'file' matches param name from form
for (BlobKey key : blobs.get("file")) {
LOGGER.info("We have a KEY!!!! " + key);
blobstoreService.delete(key); // Just testing
}
// Make this a real response
pResponse.setContentType("text/html");
pResponse.getWriter().println("OK");
}
然后你可以在你的uploadResponseHandler 中做任何事情。请求完成是 4(见此)。
myapp.ImageDrop.prototype.uploadResponseHandler = function(event)
{
if (this.xhr.readyState === myapp.ImageDrop.REQUEST_FINISHED) {
myapp.logger.fine('Request finished!');
}
};
一旦所有的部分组合在一起,就不会那么糟糕了。