2009/10/31

ABCL で Google app engine

前回は Clojure だったので今回は ABCL。 ABCL on Google App Engine を頼りにやってみる。

まずは Eclipse でプロジェクトを作る(手抜き)。

abcl.jar を war/WEB-INF/lib に ln -s して Eclipse の build pass に abcl.jar を追加。

ABCL のリポジトリにあるサンプルから AbclInit.java, HelloWorldServlet.java, first-servlet.lisp をプロジェクトのソースディレクトリにコピー。

first-servlet.lisp は Slime で C-c C-k してコンパイル。 war/fasls ディレクトリを作ってコンパイルした first-servlet.abcl をコピー。

war/WEB-INF/appengine-web.xml の application タグにアプリケーション名(ID?)を設定。

/war/WEB-INF/web.xml の servlet と servlet-mapping を設定(ABCL のリポジトリにあるサンプルそのまんま)。

だいたいこんなもんで(説明も手抜きだ)、Eclipse からプロジェクトを右クリックして Run As -> Web Application する。 http://localhost:8080/hello にアクセス。動いた。

Eclipse のエンジンボタン(?)をクリックしてデプロイしてみる。パスワード入力すればファイルがアップロードされて完了。 http://hello-abcl.appspot.com/hello 動いてる♪

日本語(というよりむしろ UTF-8)を表示したい場合は、 HelloWorldServlet.java の doGet メソッド中で、 org.armedbear.lisp.Stream を new するときに Symbol.internKeyword("UTF-8") を渡してやり、ついでに resp.setContentType("text/html; charset=utf-8"); もしておく。

public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {

LispThread currentThread = LispThread.currentThread();

SpecialBinding lastSpecialBinding = currentThread.lastSpecialBinding;
currentThread.bindSpecial(Symbol.STANDARD_OUTPUT,
new org.armedbear.lisp.Stream(resp.getOutputStream(),
Symbol.CHARACTER, Symbol.internKeyword("UTF-8")));

resp.setContentType("text/html; charset=utf-8");

try {
currentThread.execute(doGet);
} catch (ConditionThrowable condition) {
resp.setContentType("text/plain");
resp.getWriter().println(condition.toString());
} finally {
currentThread.lastSpecialBinding = lastSpecialBinding;
}
}

この例では resp.getOutputStream() を *standard-output* にバインドしているだけだが、 currentThread.execute(doGet); のことで req と resp を渡すようすれば、クエリパラメータとかもいじれるようになるよね。きっと。また今度やってみよう。

なにはともあれ Common Lisp で Google app engine できそうだ。 ABCL ありがとう。

追記。 lisp では最後に ~% とかで改行を出力するか force-output しとく必要があるような気がする。

0 件のコメント: