GAE/Jのデータストアに入れた画像データを表示する
なんというか、ブログに乗せるのもみっともないのだが、小1時間ほど悩んでしまったので、メモとして残しておく。
先のログで、Struts1.3をつかって「GAE/Jのデータストアにあるバイナリーをダウンロード」してみた。
これでは「つまらない」し、「用途が限られている」ので、「データストアに入れた画像を表示しましょう」と思ったのが発端。習慣というか摺りこみというかは恐ろしい。「画像はファイルシステムにおいて、そこにリンクをする」という先入観がある。だが、GAE/Jでは(ファイルシステムへの書き出しが禁止されているので)、これはできない。ちなみに、昔懐かしいAppletも使えない仕様になっている。それで「さてさて」となってしまった。
「あらら、imgのsrcにアクションを指定すればいいんだね」と気がつくまでに小一時間。先入観は怖い。だが、簡単にできることがわかってよかった。以下は、そうやって表示した画面。サンプルプログラムは、先のログから少しだけ変更して、2つのイメージを表示してみた。2つの画像ファイルのアップロードは、以前作成した「GAE/Jのデータストアにファイルをアップロードする」のサンプルプログラムで行う。
以下の作業は、GAE/JのプラグインがインストールされたEclipse3.4(Ganymede)で行った。Galileo版のプラグインが出ているので早く移行しなくちゃ。
プロジェクトの作成
ファイルダウンロードのサンプルを少しだけ変更するので、前回のプロジェクトをコピーして新規にプロジェクト作成をする。
Actionクラスの変更
リクエストパラメータとして、id(整数)を受け取るように変更する。このidを、Pictureエンティティーのnumber(keyとも同値になっている)に対応させる。
PictureDownloadAction.java
package test; import java.io.IOException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.actions.BaseAction; import test.entities.Picture; public class PictureDownloadAction extends BaseAction { @Override public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse res) throws IOException { String strId = req.getParameter("id"); int id = Integer.parseInt(strId); PictureDao pdao = new PictureDao(); Picture pic = pdao.getPictureById(id); String contentType = pic.getContenttype(); String filename = pic.getName(); int filesize = pic.getSize(); res.setContentType(contentType); res.setContentLength(filesize); res.setHeader("Content-Disposition", "attachment;filename=" + filename); ServletOutputStream outputStream; outputStream = res.getOutputStream(); outputStream.write(pic.getPicture().getBytes()); outputStream.flush(); return null; } }
index.htmlの作成
表示用画面は以下。なんの「取り柄もない」サンプルだが、できることが示せれば目的は果たせる。
<html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>Test of Displaying Image</title> </head> <body> <h1>Test of Displaying Image</h1> <table border="1"> <tr> <td><img src="/downloadPicture.do?id=1"/> <td><img src="/downloadPicture.do?id=2"/> </tr> </table> </body> </html>
web.xmlの変更
welcome-fileを変更したので、war/WEB-INF/web.xmlのその部分を修正する(以下は変更点のみ)。
<!-- The Usual Welcome File List --> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list>
テストとデプロイ
ローカルサーバーでテストをしたのち(このサンプルではqueryを使わないので、必ずしも必要ないが、すぐに忘れちゃうので習慣づけておく)、GAE/Jにデプロイする。
上でも述べたが、画像ファイルを抱え込んだ2つのPictureエンティティがデータ・ストアに存在することを仮定している。
それらをuploadした後、このサンプルを動かせば、イメージが表示される。