2010年4月23日金曜日

App EngineのBlobstoreにアップロードしたデータを解析する

Blobstoreのデータをアプリケーションで利用するに引き続き、どんな感じでGAEのBlobstoreにアップロードしたデータを解析しているか紹介。

とりあえず、下記のような形でPOSTとPUTをハンドルするサーブレットを作ってます。 POSTはBlobstoreにアップロードした後のリダイレクト先で、PUTはさらにそれを解析する部分です。

...
public class BlobAnalyzeServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    private static final String K_BLOB_KEY = "k";

    private transient BlobstoreService blobstore;

    @Override
    public void init() throws ServletException {
        readResolve();
    }

    private Object readResolve() {
        blobstore = BlobstoreServiceFactory.getBlobstoreService();
        return this;
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {
        Map<String, BlobKey> blobs = blobstore.getUploadedBlobs(req);
        if (blobs.size() != 1) { // この例では同時に1つだけアップロード
            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return;
        }
        BlobKey key = blobs.values().iterator().next();

        // TaskQueueを利用して裏側でdoPutを実行
        QueueFactory.getDefaultQueue().add(
            TaskOptions.Builder
                .url(req.getServletPath())
                .method(TaskOptions.Method.PUT)
                .param(K_BLOB_KEY, key.getKeyString()));

        resp.sendRedirect("/<成功した際のリダイレクト先>");
    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {
        String keyString = req.getParameter(K_BLOB_KEY);
        BlobKey blobKey = new BlobKey(keyString);
        InputStream input = new BlobInputStream(blobKey, 512 * 1024);

        // 以降、blobの内容を解析
    }
}

なお、doPutの中で使っているBlobInputStreamは、前回紹介したプログラムと同じです。第2引数の「512 * 1024」は一度にフェッチするサイズで、最大の1MBの半分を指定しています。 アップロードされたファイルの内容を直に取れるので、ファイルの内容を解析したりできます。

TaskQueueを利用している関係で、アップロードしてから解析が終わるまでに少し遅延がありますが、解析を別プロセスで行うためリクエストを速くさばけるという利点があります。

Blobstore自体の使い方は「AppEngine1.3.0 Blobstore API入門」辺りを参考にしてください。

0 件のコメント:

コメントを投稿