Slim3 + Velocity

Google App Engine for Javaを使いたくなり、評判の良さそうなフレームワークとしてSlim3を導入し、独断と偏見でJSPをやめてVelocityをテンプレートエンジンとして利用することにしました。
今回の内容は、その際の開発環境セットアップの備忘録となります。

# 開発環境

* Eclipse Classic 4.2.1 Mac OS X 64bit
* Slim3 1.0.16
* Velocity 1.6.2 + Velocity Tools 2.0

# Slim3インストール
基本的に[ここ](https://sites.google.com/site/slim3appengine/getting-started)を参考にEclipseにGoogle PluginとSlim3 Pluginをインストールします。ダウンロード先のURLがEclipseのバージョンに一致しているか確認します。今回は以下を使います。

* `https://dl.google.com/eclipse/plugin/4.2`
* `http://slim3.googlecode.com/svn/updates/`

Pluginのインストールが終わったら、Blankプロジェクトを作成します。Explorerで右クリック -> New -> Others -> Slim3と進めばOKです。上記Wikiに書いてあることのうち、workspaceの設定以外はPluginが勝手にやってくれます。

# Velocityインストール
[こちら](http://www.tdtsh.com/blog/archives/617)を参考にさせて頂きました。が、いくつか補足。

まずは、http://velocity.apache.org/download.cgi からVelocity Toolsをダウンロード、解凍します。lib内にあるvelocity-1.6.2.jarとvelocity-tools-2.0.jar、それから依存関係のあるcommonsライブラリをコピーして、
先ほど作成したBlankプロジェクトのWEB-INF/lib/にペーストし、ビルドパスに追加します。

次に、src以下にVelocityViewServletを拡張したクラスを作成します。ひとまず以下のように実装しておけばOKです。

```java
package test.hoge;

import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.velocity.Template;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.context.Context;
import org.apache.velocity.tools.view.VelocityViewServlet;

public class VelocityServlet extends VelocityViewServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected Template handleRequest(HttpServletRequest request,
            HttpServletResponse response, Context ctx) {
        String uri = request.getRequestURI();
        String templatePath = getTemplatePath(uri);

        Enumeration attrNames = request.getAttributeNames();
        while(attrNames.hasMoreElements()) {
            String key = (String) attrNames.nextElement();
            ctx.put(key, request.getAttribute(key));
        }

        Template template;
        try {
            template = Velocity.getTemplate(templatePath, "UTF-8");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return template;
    }

    protected String getTemplatePath(String uri) {
        return "/WEB-INF/template" + uri;
    }
}
```

作成したら、このサーブレットを使用するようにweb.xmlに設定を追加します。

```xml
    <servlet>
        <servlet-name>VelocityServlet</servlet-name>
        <servlet-class>test.hoge.VelocityServlet</servlet-class>
       <init-param>
            <param-name>org.apache.velocity.toolbox</param-name>
            <param-value>/WEB-INF/velocity-tools.xml</param-value>
        </init-param>
        <init-param>
            <param-name>org.apache.velocity.properties</param-name>
            <param-value>/WEB-INF/velocity.properties</param-value>
        </init-param>
        <load-on-startup>10</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>VelocityServlet</servlet-name>
        <url-pattern>*.vm</url-pattern>
    </servlet-mapping>
```

これで、拡張子が.vmのものはVelocityServletを使用するようになります。velocity-tools.xmlとvelocity.propertiesはとりあえず空でいいので作成しておきます。

次に、appengine-web.xmlに以下を追加します。ついでにセッションは有効にしておきましょう。

```xml
<sessions-enabled>true</sessions-enabled>
 <threadsafe>true</threadsafe>

    <static-files>
        <include path="**.js" />
        <include path="**.css" />
        <include path="**.png" />
        <include path="**.jpg" />
        <include path="**.jpeg" />
        <include path="**.swf" />
        <include path="**.gif" />
        <include path="**.ico" />
        <include path="**.html" />
    </static-files>
    <resource-files>
        <include path="**.jsp" />
        <include path="**.vm" />
    </resource-files>
```

# Controller + .vmファイル作成
ここまで来たら、Antのgen-controller-without-viewでSlim3のControllerを作成します。JSPファイルの代わりに手動で.vmファイルをWEB-INF/template/に作成しましょう。.vmファイルの置き場所は拡張VelocityServletに書いてあるので、WEB-INF/の好きな場所に変えてしまってOKです。
Controllerと.vmの準備が出来たら、ローカル環境でサーバを起動してブラウザでアクセスできるか確認します。

ちなみに、Slim3 + Velocityの処理の流れは大まかに以下のようになっています。

* Controller#run()が呼ばれる
* **.vmにforward
* forwardで指定された拡張子が.vmなのでVelocityServletが起動
* pathで指定された.vmファイルがレンダリングされる

Velocityを入れるとJSPに比べればパフォーマンス劣るというのをちらっと見かけたのですが、とりあえず気にせずこの環境で色々作ってみようと思います。