Spring BootとThymeleafでWebアプリを書く
よく訓練されたアップル信者、都元です。しばらくブログ業を怠っておりました。気を引き締めて、ブロガー復帰宣言。
さてここまでこのSpring Frameworkシリーズでは下記のような流れで色々紹介して来ました。
- Springの基礎
- DBの扱い方
- Spring Bootの紹介
- AWSへのデプロイ
っていうのがおさらい(適当)。ここまでは、 text/plain
を返すようなアプリケーションしか書いていませんでしたが、今回いよいよ、HTMLを返せるようにしてみたいと思います。
前回からの微調整
その前にちょっとコードの整理をしました。
mainメソッドのシンプル化
まず SpringApplication
の起動方法。static methodの run
を使って1行で起動するように簡略化して書いてみました。 → /diff
シンプルにやる場合は、起動はこれだけでいいんですね。
SpringApplication.run(BerserkerApplication.class, args);
リクエストハンドラの整理
次に、ここまでHTTPリクエストハンドラとなるメソッドを BerserkerApplication
内に書いていましたが、これをコントローラ専用のクラス RootController
を作って移動させました。通常のアプリケーションではリクエストハンドラが数個で済むことは無いので、複数のクラスを使ってハンドラを整理するのが一般的です。 → /diff
RestController から Controller へ
その上で、@RestController
というコントローラ指定をやめ、代わりに @Controller
を使うようにしました。 → /diff
@RestController
が付いたクラスにあるリクエストハンドラメソッドは、戻り値としてHTTP response bodyそのものを表すクラス(ResponseEntity
等)を返すように作ります。
一方で、@Controller
が付いたクラスでは、戻り値として「ビューの名前」を文字列で返すように作ります。 @Controller
クラスで ResponseEntity
等を直接返すように作りたい場合は、そのメソッドに @ResponseBody
を付けます。
言い換えると @RestController
はハンドラにいちいち @ResponseBody
を付けずにすませるための仕組みでした。
今回作るハンドラでは、HTTP response bodyを直接返すのではなく、HTMLビューを使いたいので、@Controller
方式に書き換えました。
ユーザ一覧のパスを "/" から "/users" に変更
最後に、今までサンプルで使ってきたDBからユーザ一覧を読み込んで表示する機能は/
ではなく/users
にマッピングしました。 → /diff
Thymeleaf
さて、Javaの世界においてHTMLのビューを司る技術は、JSPやTilesが有名かもしれません。その他にも、Velocity、Freemarkerといったテンプレートエンジンを使ったビューの構築という選択肢があります。
その中でもSpringとの相性が良く、お勧めしたいのがThymeleafです。嬉しいことに日本語のドキュメントもあります。余談ですが、Thymeleafというのは「タイムリーフ」と読むので間違いないようです。
本連載はSpring Frameworkの紹介に寄せたいので、Tyhmeleafに関するご紹介は最低限に留めたいと思っています。当ブログでも過去に何件かの記事がありますので、詳しくはそちらをご覧ください。
Spring BootアプリケーションでThymeleafを導入する
これがまた簡単なんですよ。まずは依存ライブラリとして spring-boot-starter-thymeleaf
を追加します。これだけで、Thymeleafを使う環境が整います。 → /diff
次に、src/main/resources/templates/
内にHTMLを配置します。このディレクトリに配置したindex.html
というファイルは、index
という名前のビューとして利用できます。
<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Berserker index page</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta charset="UTF-8" /> </head> <body> <p>Hello, berserker!</p> </body> </html>
最後に、/
に対するハンドラメソッドを追加します。内容としては、表示したいビュー名を文字列で返すだけです。index.html
をビューにしたいので、return "index"
としています。
以上。
恒例の、動かしてみようのコーナー
$ git clone https://github.com/classmethod-aws/berserker.git $ cd berserker $ git checkout 12.0 $ ./gradlew bootRun (略) 2016/05/25 11:30:13.711 [main] INFO o.s.b.c.e.t.TomcatEmbeddedServletContainer:162 - Tomcat started on port(s): 8080 (http) 2016/05/25 11:30:13.716 [main] INFO j.c.e.berserker.BerserkerApplication:57 - Started BerserkerApplication in 6.286 seconds (JVM running for 7.16)
起動したようなので、 http://localhost:8080/ にアクセスします。
もう、なんてことないですが、普通にHTMLが出力されました。
動的なページを作る
せっかくなら、動的に変わるページを作ってみたいですよね。というわけで、ビューを以下のように書き換えてみました。
<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Berserker index page</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta charset="UTF-8" /> </head> <body> <p>Hello, berserker!</p> <p>Now <span th:text="${now}">foobar</span></p> <ul> <li th:each="user : ${users}" th:text="${user.username}">bazqux</li> </ul> </body> </html>
そしてコントローラは、こう。引数に Model
を受け取って、そのモデルに now
と users
という名前で2つの情報を詰め込んでいます。 → /diff
@RequestMapping(value = "/", method = RequestMethod.GET) @Transactional public String index(Model model) { log.debug("index"); Iterable<User> users = userRepos.findAll(); model.addAttribute("now", new Date().toString()); model.addAttribute("users", users); return "index"; }
Spring MVCではこれ以外にもビューにモデルを渡す方法がいくつかありますが、今回は紹介しません。
さて結果は下記でお試しください。
$ git clone https://github.com/classmethod-aws/berserker.git $ cd berserker $ git checkout 12.1 $ ./gradlew bootRun