Spring Boot + Thymeleaf

# Spring Boot CLI + Thymeleafに関する自分用メモです

## Thymeleafとは
Javaのテンプレートエンジンライブラリ
アプリケーションのデータやテキストを表示するための雛型

#### \<テンプレートの必要性\>
サーバプログラムでHTML文書を全て作成させることもできますが、デザインとロジックを分離したいじゃん、というのがテンプレートの必要性。


#### \<JSPの問題点\>
JSPのスクリプトレット(<% out.println(new java.util.Date()); %>など)でJavaコードのロジック埋め込んだら、結局デザインとロジック分離できてないじゃん、というのがJSPの問題点。

#### \<Thymeleafの利点\>
比較的コードが混在しない。また、Thymeleafのタグを埋め込んだ文書でも、形式が崩れることなく、静的に開くことができる。つまり、サーバアプリでパースすることなく、HTMLブラウザ(IE,chrome,etc..)やWordPressビジュアルエディタで開いてもちゃんと表示される。この特性をナチュラルテンプレーティングという。

#### \<テンプレートモード\>
デフォルトで処理できる6種類のテンプレートのこと。
- XML
- Valid XML
- XHTML
- Valid XHTML
- HTML5
- Legacy HTML5

独自定義もできるらしい。Validは仕様に沿っていること。

## スタンダードダイアレクト
DOMを操作するタグ、と理解しておけば当座は問題なさそう。
詳細は[公式ドキュメント参照](http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf_ja.html#ダイアレクト-スタンダードダイアレクト)


### 使用例
- &lt;input type="text" name="name" th:value="${str}" /&gt;
Thymeleafでこのinput要素を処理することで、value=(strの値)が設定される。文字が入力されたテクストボックスができる。
静的にファイルを開いた際はth:...は無視される。初期値がないテクストボックスが生成される。

- &lt;p ht:text="${greeting}"&gt;Overridable String\</p\>
Thymeleafで処理すると、「Overridable String」が「${greeting}」を変換した内容に置き換わります。

#### \<変数へのアクセス\>
- ModelオブジェクトやModelAndView  
\<model\>.addAttribute(attribute_name, value);  
で、Modelオブジェクトに変数を持たせることができます。
- パラメータで渡す  
\<domain\>/profile?age=24  
のようにパラメータを渡した際、${param.age[0]}でアクセスできます。
つまり、paramにクエリパラメータ群、.key[index]で値にアクセスできます。

#### \<変数式とOGNL\>
${{ }}のように書いたブロックのことを変数式という。
変数式の中には、OGNLを書く。
OGNLは、Object-Graph Navigation Laungageの略で、Javaオブジェクトの値を参照するための式言語です。


#### \<式のユーティリティオブジェクト\>
メソッドを簡便に使用できるようにするためのオブジェクト

>
- #dates: java.util.Date オブジェクト用のユーティリティメソッド: フォーマット、コンポーネントの抽出など。
- #calendars: #dates に似ていますが java.util.Calendar オブジェクト用です。
- #numbers: 数値オブジェクト用のユーティリティメソッド。
- #strings: String オブジェクト用のユーティリティメソッド: contains, startsWith, prepending/appending, など。
- #objects: オブジェクト一般のユーティリティメソッド。
- #bools: 真偽値評価用のユーティリティメソッド。
- #arrays: 配列用のユーティリティメソッド。
- #lists: リスト用のユーティリティメソッド。
- #sets: セット用のユーティリティメソッド。
- #maps: マップ用のユーティリティメソッド。
- #aggregates: 配列やコレクション上での集約処理用ユーティリティメソッド。
- #messages: #{…} と同様に、変数式内での外部化メッセージを取り扱うためのユーティリティメソッド。
- #ids:  (例えば、イテレーション結果などの)繰り返し処理内でid属性を取り扱うためのユーティリティメソッド。  
( 引用元：[公式ドキュメント](http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf_ja.html#式のユーティリティオブジェクト) )

ここの使い方は後ほど追記します。


#### \<テキストリテラルの記述\>

```thymeleaf:literal
th:text = "You are an user of Qiita"
th:text = "'You are ' + 'an user of Qiita'"  <!-- 文字列結合(+) -->
th:text = "'You are ' + ${param.name} + '.'" <!-- 文字列結合(+) -->
th:text = "|You are ${param.name}.|"         <!-- リテラル置換(|)で変数をそのまま書ける　-->
```

#### \<メッセージ式\>
\#{...}
プロパティファイルに書いた値にアクセスできる。公式ドキュメントでは、「テキストの外部化」といっている。
ヘッダー・フッターに表示させる商標とか社名に使えそう。

1. main/resourceフォルダ配下にmessage.propertiesというファイルを作る
1. 「オブジェクト名.属性名=値」の形式で記述(改行区切り)

※ローカライズは後で追記

#### \<リンクURL式\>
@{ ドメイン以下のURL }
中に変数を入れることができる。会員ページや商品ページに使うでしょう。

#### \<選択変数式\>
*{ オブジェクト }
選択変数式を持つブロックで、オブジェクトの指定を省略することができる。

```thymeleaf:*{...}
<div th:object="${session.student}">
  <p>国語の点数：<span th:text="*{kokugo}"></span>-</p>
　<p>算数の点数：<span th:text="*{math}"></span>-</p>
</div>
```

#### エスケープしないでテキストを表示する
Thymeleafはデフォルトで、テキストを出力する際、HTMLタグをエスケープ(HTMLタグとしての効果を無効化)する。つまり、th:textで定数や変数を出力した際は、\<a href=".."\>text\</a\>などが変換されない。
th:utext
と書けば、エスケープしないで出力する。

## Model と ModelAndView の違い
- Model  
ビジネスロジックを持つ
テンプレートを利用するためのデータを持たないため、Modelオブジェクトをreturnで返してもテンプレートは表示できない。  
URLにマッピングされているメソッドで文字列を返せば、そのファイル名を持つテンプレートを開く。拡張子は不要( return "sitemap"; )
- ModelAndView   
ビジネスロジックを持っているのに加え、テンプレートを利用するためのデータを持つ
テンプレート情報を持つModelAndViewをreturnで返すことで、テンプレートを表示できる。  
ModelAndViewオブジェクトのsetViewnameでテンプレートのファイル名を渡せば、オブジェクトがテンプレートの情報を保持できる。テンプレート情報を持つModelAndViewオブジェクトを返せば、テンプレートを開くことができる。

## HTTPレスポンスが404だった際の確認事項
- RequestMappingの設定
    - @RequestMappingの属性が複数あるのに、value="/"というように属性名を指定するのを忘れていないか　　
    ※属性が1つの時は@RequestMapping("/")と省略可能
    - 遷移元のformのaction属性の値とRequestMappingがあっているか
- htmlファイルをtemplate<b>s</b>に格納しているか  
  ※ フォルダ名が違っていて、ビルドはできてもアクセス時にエラーになる事象があった。

## コメント
- &lt;!-- ... --&gt;  標準的なHTML/XMLコメント  
静的にファイルを開いた際も、Thymeleafとしてパースしても、どちらでも表示される。
- &lt;!--/\* ... \*/--&gt; パーサーレベルのコメントブロック  
Thymeleafとしてパースすると、削除される。  
静的にファイルを開いた際は、表示される。  
※複数行にまたぐ時に下記のように書いても良い。  
&lt;!--/\*--&gt;  
...  
&lt;!--\*/--&gt;  
※これは<!--/* と */--> の間にあるもの全てを完全に削除するため。  
- &lt;!--/\*/ ... /\*/--&gt; Thymeleafプロトタイプのみのコメントブロック  
Thymeleafとしてパースすると、表示される。削除される。   
静的にファイルを開いた際は、削除される。  
※*パーサーレベルのコメントブロックの逆*

### コメントと表示のされ方の対応表
書き方 | 種類 | パース後の表示有無 | 静的に開いた際の表示有無
--- | ---- | ---- | ---- 
&lt;!-- ... --&gt;|標準的なHTML/XMLコメント|タグとテキストあり|タグとテキストあり
&lt;!--/\* ... \*/--&gt;|パーサーレベルのコメントブロック|なし|タグとテキストあり
&lt;!--/\*/ ... /\*/--&gt;|Thymeleafプロトタイプのみのコメントブロック  |テキストのみあり|なし
参照：[Thymeleaf公式ドキュメント#コメントとブロック](http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf_ja.html#コメントとブロック)
※擬似的な th:block タグについては、まだ試す環境を作れていないので後日検証して追加する


## 参照
- [Thymeleaf公式ドキュメント] (http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf_ja.html)
- [SpringBootプログラミング入門](http://amzn.to/2ft4mft)
- [はじめてのSpring Boot[改訂版]](http://amzn.to/2g6hKpX)