BlobstoreService + slim3 でプチはまり
Blobstoreにファイルをアップロードするのといっしょにサーバにパラメータを渡す必要があったので、実現方法を二つほど考えたのですが、
- multipartで送る
- Blobアップロード後に呼び出されるパスにあらかじめクエリ文字列でパラメータを埋め込んでおく
どちらの方法でも渡せないのでした。いや、サーバには渡せているのだけど、どちらもslim3によって処理されないのです(前者の方法は開発環境では何故か問題ないみたい)。なので、アップロード後に呼ばれるコントローラは次のような状態です。別にこれでもいいんですけどね。。。
String id = asString("id"); // ぬるっと String id = request.getParameter("id"); // これなら取得できる
これでは不満な場合、以下のように解決できそう。
まずこんなクラスを作ってですね。。。
public class BlobUploadedRequestHander extends RequestHandler { public BlobUploadedRequestHander(HttpServletRequest request) { super(request); } @Override public void handle() { super.handle(); BlobstoreService blobstore = BlobstoreServiceFactory.getBlobstoreService(); Map<String, List<BlobKey>> map = blobstore.getUploads(request); for (Map.Entry<String, List<BlobKey>> e : map.entrySet()) { request.setAttribute(e.getKey(), e.getValue()); } } }
アップロード後の処理をするコントローラを次のように。ついでに共通の親コントローラにasBlobKeyメソッドとか定義しておくと更にすっきり。
public class UploadController extends OreOreController { @Override protected RequestHandler createRequestHandler(HttpServletRequest request) { return new BlobUploadedRequestHander(request); } @Override public Navigation run() throws Exception { Validators v = new Validators(request); v.add("id", v.required(), v.longType()); v.add("file", v.required()); if (!v.validate()) { return forward("xxx.jsp"); } long id = asLong("id"); BlobKey blobKey = asBlobKey("file"); // なんか処理 } }