Wednesday, December 5, 2012

mixer2でJSPレスなSpringMVCアプリケーションを作ってみた (Java Advent Calendar 2012)

このエントリはJava Advent Calendar 2012の5日目です。 ちなみに昨日のエントリはJavaEE Advent Calendar 2012の4日めで、こっちはEEのつかないほうのjavaです。しかも両方ともJavaかJavaEEかはどっちでもいい内容です。Adventカレンダの募集にサクサク応募してたら、うっかり連チャンになってしまってこういうややこしいことになってしまいました。w

しかもmixer2を使ったサンプルアプリケーションを、昨日のエントリではSAStrutsで、今日のエントリではSpringMVCで作るという二番煎じ一網打尽っぷり。 でも、簡単なサンプルとはいえまったく同じWebアプリを二つの代表的MVCフレームワークで作ってみると、いろいろな違いだったり共通点だったりが見えてきてなかなか面白いですよ。


目次
  1. mixer2とは?
  2. 環境の準備と、Fruit Shopアプリケーション(SpringMVC版)の起動
  3. まずテンプレートファイルを見てみよう
  4. item.htmlとItemControllerクラス
  5. 静的リソースを出力するSpringMVCの設定はたった1行


1. mixer2とは?

mixer2はJavaアプリケーション用テンプレートエンジンです。たとえばApache VelocityFreeMarkerMayaaといったソフトと同じジャンルです。

mixer2の最大の特徴は、テンプレートを100%pureなXHTMLで書けることです。

...そろそろ昨日のSAStruts編のコピペですませようとしているのがバレそうなので、mixer2の解説については昨日のエントリ本家サイトのほうをご覧ください

2. 環境の準備と、Fruit Shopアプリケーション(SpringMVC版)の起動

昨日のエントリと全く同じです。最終的にインポートするプロジェクトをmixer2-fruitshop-sastrutsではなくてmixer2-fruitshop-springmvcのほうをインポートしてください。

3. まずテンプレートファイルをみてみよう

テンプレートファイルが src/main/resources/m2mockup/m2templates にあります。 昨日のエントリではブラウザで開いてモックアップとしての使用感を体験してもらいました。そこで今日は、item.htmlをHTMLエディタで開いてみてください。

    

item name

item description here. item description here. item description here. item description here. item description here. item description here. item description here. item description here. item description here.
price amount
$99.99

<h1 id="itemName">item name</h1> や、 <span id="itemPrice">99.99</span> といった感じで、本来ならデータベース上の商品情報を埋め込むのであろう部分にダミーの値が埋め込まれています。と同時に、それらがid属性つきのH1タグやspanタグで明示的に指定されていることに注目してください。mixer2は、こうしたタグの種類やid属性をたどって値を差し替えてゆきます。(id属性じゃなくてclass属性でも置換可能)

続いてItemControllerクラスを見てみましょう。

    @RequestMapping(value = "/item/{itemId}", method = RequestMethod.GET)
    public ModelAndView showItem(@PathVariable long itemId) throws IOException, TagTypeUnmatchException {

        // load html template
        File file = ResourceUtils.getFile(mainTemplate);
        Html html = mixer2Engine.loadHtmlTemplate(file)

        // embed item box
        ItemHelper.replaceItemBox(html, itemService.getItem(itemId));

        // (途中を省略します

        ModelAndView modelAndView = new ModelAndView("mixer2view", "htmlString", mixer2Engine
                .saveToString(html));
        return modelAndView;        
    }

SpringMVCにもSAStrutsと同様に、http://.../item/999 の999の部分を自動的に変数(itemId)に割り当ててくれる、PathVariableアノテーションがあるのでそれを使っています。便利ですね。

mixer2Engine.loadHtmlTemplate(file) でテンプレートファイルを読み込んで、htmlタグの文字列をHtml型のオブジェクトに変換しています。 別につくっておいたヘルパークラスの力を借りてそのhtmlオブジェクトの内部を商品情報で差し替えて、 最後にModelAndViewクラス内にhtmlStringという文字列で格納しておきます。

mixer2view.jspがModelAndViewを受け取って、htmlStringをそのまま出力しているだけです。

ヘルパークラス、例えば ItemHelperでやっていることは、昨日のエントリの同名クラスと全く同じですので、説明は割愛させてください。

4. 静的リソースを出力するSpringMVCの設定はたった1行

さて、このサンプルアプリの静的リソース、例えばロゴ画像やstyle.cssファイルは、どうやって出力しているのでしょうか?

本来、Webアプリケーションでの静的リソースファイルは、Webアプリルート、つまりsrc/main/webapp (WEB-INF除く)に置かないと、クライアントはhttpアクセスできない、という点はSAStrutsもSpringMVCも同じです。昨日のSAStrutsでは専用のアクションクラスを作りましたが、実はSpringMVCには便利な機能があります。DispatherServletの設定ファイルをご覧ください。

  

たったこれだけです。これで、 http://.../[contextPath]/m2static/foo/bar.png へのアクセスに対して、クラスパス配下の m2mockup/m2static/foo/bar.png をDispatcherServletがレスポンスしてくれます。 cache-period="60" は、レスポンスヘッダに Cache-Control: max-age=60 を自動的に追加してくれます。便利ですね。

ただし、テンプレート上に、たとえば <img src="../m2static/img/fruitshop-logo.png" /> と書いてあると、そこは <img src="/[contextPath]/m2static/img/fruitshop-logo.png" /> に書き変える必要があります。M2staticHelperクラスでそれを一括でやっています。

そろそろお気づきの方もいるかもしれません。なぜ、HTMLモックアップを、

  • m2mockup/m2static/ の配下に静的ファイル
  • m2mockup/m2template/ の配下にテンプレートとなる*.htmlファイル
という形で格納しているのか? これは、<mvc:resources mapping="/m2static/**" location="classpath:/m2mockup/m2static/" > という1行の設定で済ませるために、わざと一番上のレベルで静的ファイルかそうでないかを分けているのです。いっしょにしてしまうと、DispatcherServletがうっかりテンプレートのhtmlファイルをそのままレスポンスしてしまう事故がありえます。そうしたことを防ぐことができます。

さて、最後はテストです。mixer2を使ってViewのレベルまでのテストをすることはもちろんなのですが、テストのフィクスチャ(事前条件となる入力値)をexcelファイルに書いておくことができる、DBUnitを使うテストケースもいくつか書いてみました。

それらについて説明を続けたいのですが、すいません、長くなりそうです。っていうかもう二日連続で濃いめのエントリを書いたのでもう限界です。^^;) このへんで、 Java Advent Calendar 2012の5日目を終えたいと思います。 次は@megascusさん!


参考書籍
Spring3入門 ――Javaフレームワーク・より良い設計とアーキテクチャ
長谷川 裕一 大野 渉 土岐 孝平
技術評論社
売り上げランキング: 8064

No comments:

Post a Comment