第5章 Thymeleafの利用
5.4 簡易ログインアプリケーションの説明(Thymeleaf版)
5.3で作成したアプリケーションをもとに、テンプレートを利用する処理が実際どのような流れで動作しているのかを説明していきます。
5.4.1 pom.xml
今回最初に行なったのは、「テンプレートエンジンを利用するためのライブラリを追加する」という作業です。冒頭で説明したThymeleafテンプレートエンジンを利用しています。
これを利用するためには、ビルドファイルにライブラリの情報を追記する必要があり、Mavenベースで作られたプロジェクトは「pom.xml」がビルドファイルとなります。Mavenは、このpom.xmlに記述されている内容を元に、必要なライブラリをダウンロードして組み込むなどでプログラムをビルドし、実行するのです。
STSを利用している場合、そのまま開くと、たくさんのフィールドが並んだ表示が現れます。これは、pomファイル編集のための専用ビジュアルエディタです。pom.xmlは、情報を正確に記述していないとプログラムをビルドできません。そこで、直接テキストを編集するのでなく、専用のフォームに記入していくことで、正確にXMLデータを構築できるようにしてあるのです。
図 5.4 1:pom.xmlを開くと、このような専用のビジュアルエディタが現れる。
エディタの下部には、いくつもの切り替えタブが並んでいます。この中から、「依存関係(Dependencies)」タブをクリックすることで、ライブラリの設定(pom.xmlファイルの <dependencies> タグに記述するもの)を行なえます。
図 5.4 2:「依存関係(Dependencies)」タブに切り替える。
左側の「依存関係(Dependencies)」という項目の右にある「追加(Add)」ボタンを押すと、追加する項目の内容を記入するダイアログが現れ、以下の項目を表示されます。
図 5.4 3:グループId(Group Id)とアーティファクトId(Artifact Id)を記入し、OKする。
これで生成されるのが、<依存関係(Dependencies)>タグ内に記述されるThymeleaf用のタグです。
【ファイル名:pom.xml】
これが、Thymeleafを利用するためのタグです。「spring-boot-starter-thymeleaf」とアーティファクトIDが指定されていることからもわかるように、これはSpringスタータープロジェクトでThymeleafを利用するためのライブラリです。これを追加することで、SpringスタータープロジェクトでThymeleafを利用する為に必要なものがすべて用意されます。
5.4.2 LoginThymeleafControllerクラス(loginFormメソッド)
次は、ログイン情報入力画面を表示する流れを確認していきましょう。
@Controller public class LoginThymeleafController { // 「/loginForm」へアクセスがあった場合 @GetMapping("/loginForm") public ModelAndView loginForm(ModelAndView mav) { // 画面に出力するViewを指定 mav.setViewName("login/form"); // ModelとView情報を返す return mav; }
まず、クラス定義の前に書かれているアノテーションが変わったことに気付いたでしょうか?@RestControllerという記述ではなく、「@Controller」というアノテーションになりました。
@Controller public class LoginThymeleafController {
@RestControllerは、あるクラスを「RESTコントローラー」という、アクセスした側にテキストを出力するだけの特殊なコントローラーにするものでした。
これに対して@Controllerは、Spring Bootの一般的なコントローラーとしてクラスを利用できるようにします。つまり@Controllerは、もっと一般的な使い方をするコントローラーの指定です。わかりやすくいえば、「テンプレートを利用してHTMLページをレンダリングし、表示する」という操作を行うページに用いられます。
テンプレートを利用してHTMLのページを表示する場合は、@RestControllerではなく@Controllerを使うと覚えておけばよいでしょう。
またloginFormメソッドを見ていると、引数がこれまでと違っていることに気が付きます。
public ModelAndView loginForm(ModelAndView mav) {
この「ModelAndView」というのが、レスポンスとして返せるクラスです。これは、その名の通り「モデル」と「ビュー」の情報をまとめて管理するクラスです。モデルとビューは、MVCの「Model」と「View」のことで、データを管理するモデルと、画面表示に関するビューをまとめて扱います。
では、loginFormメソッドではどのようなことを行なっているのでしょうか。見てみると、非常に単純なことしかしていないのがわかるでしょう。
// 画面に出力するViewを指定 mav.setViewName("login/form"); // ModelとView情報を返す return mav;
「setViewName」というメソッドを実行していますね。これは、ビューの名前を設定するためのメソッドです。これにより、「templates」フォルダから、引数に指定した名前のテンプレートをロードするようになります。
ここでは”login/form”としてありますので、「template」内からさらに「login」内の「form.html」という名前のファイルをテンプレートとして読み込むようになります(拡張子を指定する必要はありません。”form”で、自動的にform.htmlが読み込まれます)。 後は、このModelAndViewインスタンスをそのままloginFormメソッドの戻り値として返せば、この中からページのレンダリングに必要な情報を取り出してページを生成してくれる、というわけです。
5.4.3 LoginThymeleafControllerクラス(loginメソッド)
続いて、ログイン情報表示画面を表示する流れを確認していきましょう。
// 「/login」へPOST送信された場合 @PostMapping(value = "/login") // POSTデータ(必須)を受け取る public ModelAndView login(@RequestParam String id, @RequestParam String pass, ModelAndView mav) { // Viewに渡す変数をModelに格納 mav.addObject("id", "Your ID is " + id + "."); mav.addObject("pass", "PASS is " + pass + "."); // 画面に出力するViewを指定 mav.setViewName("login/success"); // ModelとView情報を返す return mav; }
今回「/loginForm」から「/login」へと送信されるデータはPOST送信されるように設定されています。
@PostMapping(value = "/login")
そのため、使用するアノテーションも@PostMappingと指定して「これはPOST用のメソッド」と明確にしてあげる必要があります。
また、テンプレートには、コントローラーから必要な値を渡して利用することができます。「addObject」というメソッドを利用して値を保管します。
// Viewに渡す変数をModelに格納 mav.addObject("id", "Your ID is " + id + "."); mav.addObject("pass", "PASS is " + pass + ".");
第1引数には、保管する値の名前、第2引数に保管する値をそれぞれ指定します。これで、指定した名前で値が保管されるようになります。今回のアプリケーションでは「id」という名前で「Your ID is ***.」という値、「pass」という名前で「PASS is ***.」という値を保管しています。その値がテンプレート側に渡されることになります。
mav.addObject( [保管する値の名前], [保管する値] );
5.4.4 success.html
最後に、ログイン情報表示画面のテンプレート側の処理を確認していきましょう。
ここでは、「th:text」という属性が追加されています。これは、Thymeleaf独自の属性です。
Thymeleafによってページ内容がレンダリングされる際、こうした「th:○○」という独自属性の値がタグの値に置き換えられてレンダリングされるようになります。独自の属性ですから、レンダリングされなければ、表示にはまったく影響を与えません。
例えば、何らかの理由でこのsuccess.htmlが直接表示されたような場合には、<span>タグに用意されたテキストがそのまま表示されるだけです。Thymeleaf用に記述した情報が表示に悪影響を及ぼすことはありません。
このth:textには、「${id}」「${pass}」という値が記述されています。これは、あらかじめ用意された「id」「pass」という変数をここに埋め込むことを示します。Thymeleafでは、このように記述してコントローラー側で用意した値をここに出力することができます。
注意したいのは、「埋め込む値は、必ずThymeleaf用に用意された属性の値として用意する」という点です。例えば${id}という値を、
このように埋め込んでもいいんじゃないか? と思うかもしれません。が、これは違います。このようにすると、ただ「${id}」という文字が表示されるだけです。${id}はThymeleaf用に用意された値とはみなされず、コントローラーで用意した値に変換されません。必ずth:○○という属性の値に埋め込むようにしましょう。