第46夜 JAX-RSをWebアプリのフロントエンドとして利用する その3
しかしテンプレートが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は問題ないのがわかる。
さぁ、これで完全にサーブレット/JSPのAPIから解き放たれた。カスタマイズはほかにもいろいろと出来るようになっているのでJAX-RSマジオススメ。