1

Google App Engine バックエンドに接続する JavaScript フロントエンドがあります。Blobstoreにファイルをアップロードする手順は、 JSP を使用していることを前提としていますが、私はそうではありません。ファイル ドロップ ハンドラーを作成する例では、投稿でファイルを単独で送信することを想定しています。

これは、ファイルを送信するために機能します。

var files = event.getBrowserEvent().dataTransfer.files;
if (files.length > 0) {
  if (files.length > 1) {
    console.log('Too many files!');
  } else {
    var file = files[0];

    var xhr = new goog.net.XmlHttp();
    xhr.open('POST', '/imageUpload?gwt.codesvr=localhost:9997');
    xhr.send(file);
  }
}

しかし、これはデータをサーブレットに直接送信しているだけです。HTML にフォームを追加することはできますが、クロージャーがタイプ file の入力を設定するのを好まないことがわかる限りです。

ファイルを Blobstore にアップロードする方法についての提案はありますか?

4

1 に答える 1

0

この答えの助けを借りて、私はついにこれを理解しました。

まず、appengine-web.xml でセッションが有効になっていることを確認します。<sessions-enabled>true</sessions-enabled>

アップロード URL を作成するサーブレットと、画像がブロブストアに書き込まれた後にリダイレクトを処理するサーブレットの 2 つの別個のサーブレットを作成することになりました。

画像アップロード URL サーブレット

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);
};

画像アップロード リダイレクト サーブレット

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!');
  }
};

すべてのピースが集まったら、それほど悪くはありません。

于 2012-11-26T07:15:10.297 に答える