以前本サイトにて、ブロブストアに画像を保存する方法について解説しました。
ブロブストアに保存したファイルには、それぞれ固有の「ブロブキー(BlobKey)」が割り振られます。
ブロブキーを利用することで、ブロブストアに保存した画像ファイルの情報を取得したり、画像ファイルのURLを取得することができます。
今回はそのブロブキーの取り扱いについて解説したいと思います。
今回の解説するサンプルでは、以下の図のように、トップ画面の一覧ボタンを押すと、ブロブストアに保存されている画像ファイルの情報を取得して表示するようにします。
- ブロブストアからブロブキーを取得
- 取得したブロブキーから文字列(以後ブロブキー名)を取得
- ブロブキー名をデータストアに保存
- データストアに保存したブロブキー名を取得し、ブロブキー名からブロブキーを生成
- 生成したブロブキーから、画像ファイルの情報を取得する
それでは続きで詳しく見ていきます。
ブロブストアからブロブキーを取得する
まずは、ブロブストアに画像ファイルをアップロードする際に、画像ファイルのブロブキーを取得します。
同時に、取得したブロブキーから文字列(ブロブキー名)を取得します。
今回のサンプルでは、画像のアップロードは、UploadServlet.javaファイルでPOSTメソッドにて行っています。なお、画像のアップロードについてはこちらで解説しています。ファイル名なども同じですので参考にしてください。
ここで、ブロブストアに保存した画像ファイルのブロブキーを取得してみます。
以下のソースコードをご覧ください。
UploadServlet.java
private BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService(); public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { int i = 1; // ブロブキーの取得 Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req); DatastoreService dss = DatastoreServiceFactory.getDatastoreService(); for(String tag : blobs.keySet()){ Entity entity = new Entity(KeyFactory.createKey("myBlob", i)); BlobKey blobKey = blobs.get(tag); // BlobKeyを文字列に変換 String strBlobKey = blobKey.getKeyString(); entity.setProperty("BlobKey",strBlobKey); dss.put(entity); i++; } resp.sendRedirect("/imageuploader"); }
7行目で、 BlobstoreService クラスの getUploadedBlobsメソッドを用いてブロブストアに保存されている画像ファイルのブロブキーをMapで取得しています。
10行目で、Mapのキーを取り出しつつ、forループを回しています。
ここで取得できるキーは、画像のアップロード時にinputタグのnameプロパティーに指定した値です。
12行目で、Mapの取り出したキーを元に、Mapからブロブキーを取得しています。
14行目で、取得したブロブキーを、getKeyStringメソッドを用いて文字列(ブロブキー名)に変換します。
今回のサンプルでは、データストアを利用してブロブキー名を保存し、後ほど一覧画面で情報を表示する際に取り出すようにします。
そのために、15、16行目で、ブロブキー名をデータストアに保存します。(データストアへのデータの保存方法についてはこちらの記事をご覧ください)
ブロブキーから情報を取得する
ブロブキー名をデータストアに保存したら、次はそれを取り出してブロブキーを生成します。
生成したブロブキーを用いてブロブストアから画像ファイルの情報を取得し、一覧として表示します。
図:一覧画面
なお今回のサンプルでは、ブロブストアに2つの画像ファイルを保存していますので、データストアに保存しているブロブキーも2つ存在します。よって、データストアから複数のデータを取得する方法についても簡単に解説していきます。
以下のソースコードは、一覧画面遷移時に呼ばれるソースコードです。
BlobListServlet.java
DatastoreService dss = DatastoreServiceFactory.getDatastoreService(); BlobInfoFactory factory = new BlobInfoFactory(); public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { Velocity.init(); Query query = new Query("myBlob"); List entityList = dss.prepare(query).asList(FetchOptions.Builder.withOffset(0)); List list = new ArrayList(); for(int i=0; i<entityList.size(); i++){ String blobStr = entityList.get(i).getProperty("BlobKey").toString(); BlobKey blobKey = new BlobKey(blobStr); BlobInfo blobInfo = factory.loadBlobInfo(blobKey); String fileName = blobInfo.getFilename(); list.add(fileName); } VelocityContext vContext = new VelocityContext(); // URLのバインド vContext.put("list", list); resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); Template template = Velocity.getTemplate("WEB-INF/bloblist.vm", "Shift-JIS"); template.merge(vContext, resp.getWriter()); }
まずはデータストアから複数のデータを取得する方法から見て行きます。(データを一つだけ取得する方法についてはこちらで解説しています)
まずは8行目で、クエリを生成しています。Queryクラスのコンストラクタの引数にはカインド名を指定します。
Queryクラスは、データストアに対してデータ取得の条件を指定するためクラスです(※クエリについては、また別の機会に詳しく解説したいと思います)。
9行目で先ほどのクエリを利用して、コンストラクタの引数に指定した「myBlob」カインドにあるすべてのエンティティーをリスト形式で取得しています。
以下の記述は、データを何番目から取得したいかを指定しています。
FetchOptions.Builder.withOffset(0)
今回は、最初のエンティティー(0番目)から取得したいので、 withOffsetに「0」を指定しています。
さて、ブロブキー名が保存されているエンティティーは取得できたので、そこから値を取り出します。
12〜18行目のfor文内に注目してください。
まず12行目で、「BlobKey」プロパティーに格納したブロブキー名をエンティティーから取得しています。
次に13行目で、取得したブロブキー名から、ブロブキーを生成しています。
こうすることで、文字列に変換する前と同じブロブキーを生成することが可能です。
14行目で、生成したブロブキーを用いてBlobInfoを取得しています。
15行目で、取得したBlobInfoからファイル名を取得しています。
16行目で、ファイル名をリストに詰め込んでいます。
※BlobInfoクラスお扱いについてはこちらの記事を参考にしてください。
20行目以降は、Veocity Templateにデータをバインドするお決まりの処理です。
ここでのバインド処理についてはこちらの記事と同じ方法ですので省略します。参考にしてみてください。
まとめ
今回は、以下の順序でブロブキーを取り扱いました。
- ブロブストアに保存した画像ファイルのブロブキーを取得
- 取得したブロブキーを文字列(ブロブキー名)に変換してデータストアに保存
- データストアに保存したブロブキー名からブロブキーを生成
- 生成したブロブキーからブロブストアに保存したファイルのBlobInfoを取得
今回はブロブキーの取り扱いとデータストアの使い方の解説のために、一例としてブロブキーから取得した文字列をデータストアに保存してみました。
各種キーの取り扱いについては、状況に応じてベストな方法を考えてみてください。