第46夜 JAX-RSをWebアプリのフロントエンドとして利用する その3

第43夜第45夜の続き。

前回でJAX-RSからサーブレットAPIは消えた。

しかしテンプレートがJSPではサーブレットAPIが残ったままだ。


43回でチラッとだけ書いた(「今回は」JSP)が、テンプレートを自由に設定できるのがJersey(JAX-RS参照実装)の強みだ。

ためしにVelocityを使ってみよう。


テンプレート。index.vmという名前にしてある。

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <h1>${it.a} + ${it.b} = ${it.c}</h1>
    </body>
</html>


JAX-RSのソースは一切変更なし。

@Path("calc")
public class CalcResource {
    @Path("{a}/{b}")
    @GET
    public Viewable add(@PathParam("a")int a, @PathParam("b")int b) {
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("a", a);
        params.put("b", b);
        params.put("c", a + b);

        return new Viewable("/index.jsp", params);
    }
}


Velocityをテンプレートとして登録。JSPのときと同じように「it」でわたしてある。

@Provider
public class CustomTemplate implements ViewProcessor<Template> {
    public CustomTemplate(){
        Properties p = new Properties();
        p.setProperty("resource.loader", "CLASSPATH");
        p.setProperty("CLASSPATH.resource.loader.class",
                "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
        Velocity.init(p);
    }
    @Override
    public Template resolve(String path) {
        Template template = Velocity.getTemplate(path, "UTF-8");
        return template;
    }

    @Override
    public void writeTo(Template t, Viewable vwbl, OutputStream out) throws IOException {
        Writer writer = new OutputStreamWriter(out,"UTF-8");
        Context context = new VelocityContext();
        context.put("it", vwbl.getModel());
        t.merge(context, writer);
        writer.flush();
    }
    
}

アノテーションつけてるので起動時に自動登録される。
resolveメソッドにはテンプレートのパスが渡ってくる。相対だったり絶対だったり(スラッシュから始まるもの)したものをちゃんと解釈して渡してくれる。
writeToはそのまま出力する部分。resolveの戻り値とViewableがわたってくるのでそれを元にストリームに流すだけ。自由なテンプレートが使えるというのがわかるだろう。

アクションベースのフレームワークとしてJAX-RSは問題ないのがわかる。

さぁ、これで完全にサーブレット/JSPAPIから解き放たれた。カスタマイズはほかにもいろいろと出来るようになっているのでJAX-RSマジオススメ。