Thymeleaf  自分用メモ  crossfish21 

一気に全部書く

```
Controllerから渡されたObjectの値を取得する

package p1.controllers01;

@Controller
public class Controller09 {
	
	@RequestMapping("pages01/09")
	public ModelAndView aaa(ModelAndView mav) {
		mav.addObject("value1","VALUE1");
		mav.addObject("value2","VALUE2");
		mav.addObject("value3","VALUE3");
		mav.setViewName("pages01/page09");
		return mav;
	}
}



<body>
	<h2>Page09</h2>
	<p>value1の値は<span th:text="${value1}"></span></p>
	<!-- ${変数名} で取得できる -->
	<p th:text="'value2の値は: ' + ${value2}"></p>
	<p th:text="${value3}"></p>
</body>





パラメータの値を取得する

package p1.controllers01;

@Controller
public class Controller10 {
	
	@RequestMapping("pages01/10")
	public ModelAndView aaa(ModelAndView mav) {
		mav.setViewName("pages01/page10");
		return mav;
		// pages01/10?aaa=AAA&bbb=BBB でアクセスしてみる
	}
	
	@RequestMapping("pages01/11")
	public ModelAndView bbb(ModelAndView mav) {
		mav.setViewName("pages01/page11");
		return mav;
		// pages01/11?zzz=CCC&zzz=DDD&yyy=111&yyy=222 でアクセスしてみる
	}
}




<body>
	<h2>Page10</h2>
	<p th:text="'aaa値: '+ ${param.aaa}"></p>
	<p th:text="'bbbの値: '+ ${param.bbb}"></p>
</body>



<body>
	<h2>Page11</h2>
	<p th:text="'zzzの第1要素の値: '+ ${param.zzz[0]}"></p>
	<p th:text="'zzzの第2要素の値: '+ ${param.zzz[1]}"></p>
	<p th:text="'yyyの第1要素の値: '+ ${param.yyy[0]}"></p>
	<p th:text="'yyyの第2要素の値: '+ ${param.yyy[1]}"></p>
	<!--  同名のパラメータが複数ある場合は、配列として受け取ることができる -->
</body>





文字列と文字列を結合する　文字列と変数の値を結合する

<body>
	<p>文字列を結合：<span th:text="'aaa ' + 'bbb ' + 'ccc'"></span></p>
	<p>文字列と変数の値を結合：<span th:text="'messageの値は' + ${message}"></span></p>
</body>


※コントローラ-から、mav.addObject("message","XYZ");　で受け取っている





プロパティファイルから値を取得する

package p1.controllers01;

@Controller
public class Controller11 {
	
	@RequestMapping("pages01/12")
	public ModelAndView aaa(ModelAndView mav) {
		mav.setViewName("pages01/page12");
		return mav;
	}
}


<body>
	<h2>Page12</h2>

	<!-- src/main/resources 配下に、messages.propertiesという名前でプロパティファイルを用意してある。内容は以下
	 message.text01=MESSAGE_TEXT01
	 message.text02=MESSAGE_TEXT02
	 message.text03=MESSAGE_TEXT03
	 message.text04=\u65E5\u672C\u8A9E\u30E1\u30C3\u30BB\u30FC\u30B8
	 -->

	<p>messages.propertiesから値を取得：<span th:text="'message.text01の値は' + #{message.text01}"></span></p>
	<!-- messages.propertiesのmessage.text01の値を取得 。#{message.text01}であることに注意。${}ではない-->
	<p>messages.propertiesから値を取得：<span th:text="'message.text02の値は' + #{message.text02}"></span></p>
	<p>messages.propertiesから値を取得：<span th:text="'message.text03の値は' + #{message.text03}"></span></p>
	<p>messages.propertiesから日本語の値を取得：<span th:text="'message.text04の値は' + #{message.text04}"></span></p>
	<!-- 日本語の値も設定･取得可能。全角文字を***.properteisファイルの値に入力すると、自動でUnicodeに変換される -->
</body>





リンクを作成する。パラメータ値を渡すことも可能　　※リンクへのパスの先頭に"/"が必要なことに注意

package p1.controllers01;

@Controller
public class Controller12 {
	
	@RequestMapping("pages01/13")
	public ModelAndView aaa(ModelAndView mav) {
		mav.setViewName("pages01/page13");
		return mav;
		// pages01/13?param1=1234 でアクセスしてみる
	}
	
	@RequestMapping("pages01/14")
	public ModelAndView bbb(ModelAndView mav) {
		mav.setViewName("pages01/page14");
		return mav;
	}
	
	@RequestMapping("pages01/15")
	public ModelAndView ccc(ModelAndView mav) {
		mav.setViewName("pages01/page15");
		return mav;
	}
	
	@RequestMapping("pages01/16/{aaa}/{bbb}")
	public ModelAndView ddd(ModelAndView mav, @PathVariable String aaa, @PathVariable String bbb) {
		mav.addObject("aaa",aaa);
		mav.addObject("bbb",bbb);
		mav.setViewName("pages01/page16");
		return mav;
	}
	
	@RequestMapping("pages01/17/{num}")
	public ModelAndView eee(ModelAndView mav, @PathVariable String num) {
		mav.addObject("num",num);
		mav.setViewName("pages01/page17");
		return mav;
	}
}


<body>
	<h2>Page13</h2>
	<p><a th:href="@{/pages01/14}">page14へのリンク</a></p>
	<!-- 通常のリンク パスの先頭に"/"が必要なことに注意-->
	
	<p><a th:href="@{/pages01/15(param1=${'abc'},param2=${'def'})}">パラメータを渡すpage15へのリンク</a></p>
	<!-- パラメータをリンク先に渡す。 /pages01/page15?param1=abc&param2=def と同じ意味になる -->
	
	<p><a th:href="@{/pages01/16/{aaa}/{bbb}(aaa=${'AAA'},bbb=${'BBB'})}">"page01/aaa/"形式でパラメータを渡すpage16へのリンク</a></p>
	<!-- パラメータをリンク先に渡す。 /pages01/page15?param1=abc&param2=def と同じ意味になる -->
	
	<p><a th:href="@{/pages01/17/{num}(num=${param.param1})}">受け取ったパラメータの値をリンク先へ渡すpage15へのリンク</a></p>
	<!-- このように受け取ったパラメータの値をリンクに埋め込むことも可能 -->
</body>



<body>
	<h2>Page14</h2>
</body>



<body>
	<h2>Page15</h2>
	<p th:text="'param1の値:' + ${param.param1}"></p>
	<p th:text="'param2の値:' + ${param.param2}"></p>
</body>



<body>
	<h2>Page16</h2>
	<p th:text="'aaaの値:' + ${aaa}"></p>
	<p th:text="'bbbの値:' + ${bbb}"></p>
</body>



<body>
	<h2>Page17</h2>
	<p th:text="'numの値:' + ${num}"></p>
</body>





BeanクラスのインスタンスをViewに渡し、フィールドの値を出力する

package p1.controllers01;

import p1.beans.Bean01;

@Controller
public class Controller13 {
	
	@RequestMapping("pages01/18")
	public ModelAndView aaa(ModelAndView mav) {
		mav.setViewName("pages01/page18");
		Bean01 bean01 = new Bean01("STR1","STR2","STR3");
		// Bean01のインスタンス生成
		mav.addObject("bean01",bean01);
		return mav;
	}
}



<body>
	<h2>Page18</h2>
	<table th:object="${bean01}">
	<!-- th:object= でオブジェクトを取得 -->
		<tr><th>str1</th><td th:text="*{str1}"></td></tr>
		<!-- th:text="*{フィールド名}" でフィールドの値を取得-->
		<tr><th>str2</th><td th:text="*{str2}"></td></tr>
		<tr><th>str3</th><td th:text="*{str3}"></td></tr>
	</table>
</body>


package p1.beans;

import java.io.Serializable;

public class Bean01 implements Serializable {

	private String str1;
	private String str2;
	private String str3;
	
	public Bean01(String str1, String str2, String str3) {
		this.str1 = str1;
		this.str2 = str2;
		this.str3 = str3;
	}
	
	public String getStr1() {
		return str1;
	}
	public void setStr1(String str1) {
		this.str1 = str1;
	}
	public String getStr2() {
		return str2;
	}
	public void setStr2(String str2) {
		this.str2 = str2;
	}
	public String getStr3() {
		return str3;
	}
	public void setStr3(String str3) {
		this.str3 = str3;
	}
}




+を使わずに文字列と変数を連結する　　th:text="|名前は ${name}。年齢は ${age} です。|　のような形

package p1.controllers01;

@Controller
public class Controller14 {
	
	@RequestMapping("pages01/19")
	public ModelAndView aaa(ModelAndView mav) {
		mav.setViewName("pages01/page19");
		mav.addObject("name","永井");
		mav.addObject("age",18);
		return mav;
	}
}


<body>
	<h2>Page19</h2>
	<p th:text="|名前は  ${name}、年齢は  ${age}才です|"></p>
	<!-- || で囲むと、文字列と変数をそのまま並べることができる -->
</body>





HTMLコードとして動作するように出力する
※th:text=""  だと、標準でHTMLエスケープされている

package p1.controllers01;

@Controller
public class Controller15 {
	
	@RequestMapping("pages01/20")
	public ModelAndView aaa(ModelAndView mav) {
		mav.setViewName("pages01/page20");
		mav.addObject("str1","<script>window.alert('str1の警告')</script>");
		mav.addObject("str2","<script>window.alert('str2の警告')</script>");
		mav.addObject("str3","<span>SPAN</span>");
		return mav;
	}
}


<body>
	<h2>Page20</h2>
	<p th:text="${str1}"></p>
	<!--  th:text= だと、HTMLエスケープされているのでHTMLコードとしては発動しない  -->
	
	<p th:utext="${str2}"></p>
	<!--  th:utext= だと、HTMLエスケープされないのでHTMLコードとして発動する。スクリプトコードとしても動作してしまう  -->
	<p th:utext="${str3}"></p>
	<!--  こちらもHTMLコードとして動作する。ソースを確認してみよう  -->
</body>




IF文のような条件式

package p1.controllers01;

@Controller
public class Controller16 {
	
	@RequestMapping("pages01/21/{num}")
	public ModelAndView aaa(ModelAndView mav,@PathVariable int num) {
		mav.setViewName("pages01/page21");
		// 条件1を設定
		mav.addObject("num",num);
		mav.addObject("formula1",num > 100);  // 条件式の条件を設定
		mav.addObject("trueValue1","100より大きいです");  // trueの場合の出力文字を設定
		mav.addObject("falseValue1","100以下です");  // falseの場合の出力文字を設定
		
		// 条件2を設定
		mav.addObject("formula2",num % 2 == 0);
		mav.addObject("trueValue2","偶数です");
		mav.addObject("falseValue2","奇数です");
		return mav;
	}
}


<body>
	<h2>Page21</h2>
	<p th:text="${num} + 'は' + (${formula1} ? ${trueValue1} : ${falseValue1})"></p>
	<!--  Javaの3項条件式と同じ条件分岐を実現  -->
<br>
	<p th:if="${formula2}" th:text="${num} + 'は' + ${trueValue2}"></p>
	<!-- 条件がtrueの場合に出力する。条件がfalseの場合は、ソースに出力されない -->
	
	<p th:unless="${formula2}" th:text="${num} + 'は' + ${falseValue2}"></p>
	<!-- 条件がfalseの場合に出力する。条件がtrueの場合は、ソースに出力されない -->
<br>
	<p th:if="0" th:text="0は真扱いです"></p>
	<p th:unless="0" th:text="0は偽扱いです"></p>
	<!-- 0,"off","no"などの値はfalseとして扱うらしい。それ以外はtrueとして判定されるらしい -->
</body>




switch式

<title>Page20</title>
</head>
<body>
	<p>PAGE20</p>
	<div th:switch="${formula1}">
		<p th:case="0" th:text="${num} + 'を5で割った余りは0です'"></p>
		<p th:case="1" th:text="${num} + 'を5で割った余りは1です'"></p>
		<p th:case="2" th:text="${num} + 'を5で割った余りは2です'"></p>
		<p th:case="3" th:text="${num} + 'を5で割った余りは3です'"></p>
		<p th:case="4" th:text="${num} + 'を5で割った余りは4です'"></p>
		<p th:case="*" th:text="異常な数値"></p>
		<!-- Javaのdefaultに相当する -->
	</div>
</body>





	@RequestMapping("/page20/{num}")
	public ModelAndView aaa(ModelAndView mav,@PathVariable int num) {
		mav.setViewName("page20");
		mav.addObject("num",num);
		mav.addObject("formula1",num % 5);  // 条件式の条件を設定
		return mav;
	}
	
	




繰り返し構文　th:each

package p1.controllers01;

@Controller
public class Controller17 {
	
	@RequestMapping("pages01/22")
	public ModelAndView aaa(ModelAndView mav) {
		mav.setViewName("pages01/page22");
		
		List<String[]> arrayList = new ArrayList<>();
		arrayList.add(new String[]{"aaa","bbb","ccc"});
		arrayList.add(new String[]{"123","456","789"});
		arrayList.add(new String[]{"あああ","いいい","ううう"});
		mav.addObject("arrayList",arrayList);
		
		List<Bean02> bean02List1 = new ArrayList<>();
		bean02List1.add(new Bean02("岩崎","新潟県","ラーメン"));
		bean02List1.add(new Bean02("伊藤","富山県","イメージファイト"));
		bean02List1.add(new Bean02("永井","長野県","音楽"));
		mav.addObject("bean02List1",bean02List1);
		
		List<Bean02> bean02List2 = new ArrayList<>();
		bean02List2.add(new Bean02("大石","大分県","適当1"));
		bean02List2.add(new Bean02("鈴木","北海道","適当2"));
		bean02List2.add(new Bean02("佐藤","庄田","適当3"));
		mav.addObject("bean02List2",bean02List2);
		return mav;
	}
}


<body>
	<h2>Page22</h2>
	<p>配列リストの内容</p>
	<table>
		<tr>
			<th>第1要素</th>
			<th>第2要素</th>
			<th>第3要素</th>
		</tr>
		<tr th:each="obj1:${arrayList}">
			<td th:text="${obj1[0]}"></td>
			<td th:text="${obj1[1]}"></td>
			<td th:text="${obj1[2]}"></td>
		</tr>
	</table>
	<br>
	<p>Bean02リスト1の内容</p>
	<table>
		<tr>
			<th>名前</th>
			<th>住所</th>
			<th>備考</th>
		</tr>
		<tr th:each="obj2:${bean02List1}">
			<td th:text="${obj2.name}"></td>
			<td th:text="${obj2.address}"></td>
			<td th:text="${obj2.note}"></td>
		</tr>
	</table>
	<br>
	<p>Bean02リスト2の内容</p>
	<table>
		<tr>
			<th>名前</th>
			<th>住所</th>
			<th>備考</th>
		</tr>
		<!-- 一応このようにも書ける。かえってややこしいかな -->
		<tr th:each="obj3:${bean02List2}" th:object="${obj3}">
			<td th:text="*{name}"></td>
			<td th:text="*{address}"></td>
			<td th:text="*{note}"></td>
		</tr>
	</table>
</body>


package p1.beans;

public class Bean02 implements Serializable {

	private String name;
	private String address;
	private String note;
	
	public Bean02(String name, String address, String note) {
		this.name = name;
		this.address = address;
		this.note = note;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public String getNote() {
		return note;
	}
	public void setNote(String note) {
		this.note = note;
	}
}





繰り返し構文　th:each　で、現在の要素の情報を取得する
※何番目の要素か、最初の要素であるか、奇数番目の要素であるか、など　結構使い道はあるかも

package p1.controllers01;

@Controller
public class Controller18 {
	
	@RequestMapping("pages01/23")
	public ModelAndView aaa(ModelAndView mav) {
		mav.setViewName("pages01/page23");
		
		List<String[]> arrayList = new ArrayList<>();
		arrayList.add(new String[]{"aaa","bbb","ccc"});
		arrayList.add(new String[]{"123","456","789"});
		arrayList.add(new String[]{"あああ","いいい","ううう"});
		mav.addObject("arrayList",arrayList);
		return mav;
	}
}


<style type="text/css">
td,th{ border: 1px solid; }
table{ table-layout: auto; border-collapse: collapse;}
</style>
</head>
<body>
	<h2>Page23</h2>
	<p>配列リストの内容</p>
	<table>
		<tr>
			<th>第1要素</th>
			<th>第2要素</th>
			<th>第3要素</th>
			<th>0から始まる、現在のインデックス</th>
			<th>1から始まる、現在のインデックス</th>
			<th>繰り返し変数の全要素数</th>
			<th>現在の要素オブジェクト</th>
			<th>現在の繰り返し位置が偶数であるか</th>
			<th>現在の繰り返し位置が奇数であるか</th>
			<th>最初の要素であるか</th>
			<th>最後の要素であるか</th>
		</tr>
		<tr th:each="obj1,status :${arrayList}">
		<!-- status が、変数arrayListの属性値を取得するための変数になる。別に"status"という変数名でなくてもいい -->
			<td th:text="${obj1[0]}"></td>
			<td th:text="${obj1[1]}"></td>
			<td th:text="${obj1[2]}"></td>
			<td th:text="${status.index}"></td>
			<!-- status.index で、0から始まる、現在のインデックスを取得 -->
			<td th:text="${status.count}"></td>
			<td th:text="${status.size}"></td>
			<td th:text="${status.current}"></td>
			<td th:text="${status.even}"></td>
			<td th:text="${status.odd}"></td>
			<td th:text="${status.first}"></td>
			<td th:text="${status.last}"></td>
		</tr>
	</table>
</body>





プリプロセッシング    変数の内容を事前に評価させる　　__${value}__   のような形
※  th:object="${customers.get(${one})}"   のような形で、"one"に1が格納されていたとしても、エラーになってしまう。これを防ぐためのもの

package p1.controllers01;

@Controller
public class Controller19 {
	
	@RequestMapping("pages01/24")
	public ModelAndView aaa(ModelAndView mav) {
		mav.setViewName("pages01/page24");
		
		List<String> list1 = new ArrayList<>();
		list1.add("aaa");
		list1.add("bbb");
		list1.add("ccc");
		mav.addObject("list1",list1);
		mav.addObject("index1",1);
		
		// リストの要素をリストにしてみる
		List<List<String>> list2 = new ArrayList<>();  //外側のリスト
		List<String> innerList1 = new ArrayList<>();  //内側のリスト1
		innerList1.add("AAA");
		innerList1.add("BBB");
		innerList1.add("CCC");
		List<String> innerList2 = new ArrayList<>();  //内側のリスト2
		innerList2.add("XXX");
		innerList2.add("YYY");
		innerList2.add("ZZZ");
		list2.add(innerList1);
		list2.add(innerList2);
		mav.addObject("list2",list2);
		mav.addObject("index2",0);
		mav.addObject("index3",2);
		
		return mav;
	}
}





th:inline="text"  で、各要素にth:textと書くことを省略する。[[${変数名}]]  で、テキストとして出力可能
※ th:inline="javascript"  とすることで、javascriptのコード内でも変数を出力可能

package p1.controllers01;

@Controller
public class Controller20 {
	
	@RequestMapping("pages01/25")
	public ModelAndView aaa(ModelAndView mav) {
		mav.setViewName("pages01/page25");
		mav.addObject("value1","aaa");
		mav.addObject("value2","bbb");
		mav.addObject("value3","ccc");
		mav.addObject("value4","ddd");
		mav.addObject("message","本日は晴天なり");
		return mav;
	}
}




<script th:inline="javascript">  <!-- これでjavascriptコード内で変数の出力が可能になる -->
function aaa(){
	window.alert(/*[[${message}]]*/);
}
</script>
</head>
<body>
	<h2>Page25</h2>
	<div th:inline="text">  <!-- これでこのdivブロック内の要素で、テキストとして出力可能になる -->
		<p>value1の値：[[${value1}]]</p>
		<p>value2の値：[[${value2}]]</p>
		<p>value3の値：[[${value3}]]</p>
		<p>value4の値：[[${value4}]]</p>
	</div>
	<br>
	<p><button onclick="aaa()">メッセージ出力</button></p>
</body>




別ファイルのコードをincludeする　　※ファイルのコード全体をincludeするのではなく、一部分を指定してincludeできるのが便利

package p1.controllers01;

@Controller
public class Controller21 {
	
	@RequestMapping("pages01/26")
	public ModelAndView aaa(ModelAndView mav) {
		mav.setViewName("pages01/page26");
		return mav;
	}
}



***********   includeされるパーツのファイル  templates/parts/parts01  ****************

<!DOCTYPE html>
<html xmlns="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
</head>
<body>
<!-- このページのファイルパスは、templates/parts/parts01   -->
	<p th:fragment="fragment01">includeされるパーツ01</p>
	<!-- th:fragment= で、includeされる部分として定義。 fragment01はパーツに名前を付けている-->
	<p th:fragment="fragment02">includeされるパーツ02</p>
</body>
</html>



***********   includeする側   ********************

<body>
	<h2>Page26</h2>
	<p th:include="/parts/parts01 :: fragment01"></p>
	<!-- th:include="で、includeするパーツを指定する。 /parts/parts01  はファイルのパス。fragment01はincludeする部分の名前-->
	<p th:include="/parts/parts01 :: fragment02"></p>
	
	<!-- 出力は以下になる
	includeされるパーツ01
	includeされるパーツ02
	
	ソースは以下になっている
	<p>includeされるパーツ01</p>
	<p>includeされるパーツ02</p>
	 -->
</body>





ラジオボタン、チェックボックス、セレクトボックスに初期値(チェック)を入れる方法
※複数選択のセレクトは結構面倒

************    データアップ用ページ(dataUp04)    ****************

th{ border: 1px solid; background-color: #B1F9D0}
td{ border: 1px solid; }
table{ border-collapse: collapse;}
.errorClass{background-color: #FFCCFF}
</style>
</head>
<body th:object="${dataModel}">
	<h2>DataUp04</h2>
		<ul>
			<li th:each="error : ${#fields.detailedErrors()}" th:text="${error.message}">
		</ul>
	<form action="/jpa/insert04" method="POST" >
		<table>
			<tr>
				<th>id</th>
				<td>
					<input type="text" name="id" th:value="*{id}" th:errorclass="errorClass">
					<div th:if="${#fields.hasErrors('id')}" th:errors="*{id}"></div>
				</td>	
			</tr>
			<tr>
				<th>radio1</th>
				<td>
					<label for="radio1_1">開発課</label><input type="radio" id="radio1_1" name="radio1" value="開発課" 
					th:checked="${dataModel.radio1 == '開発課'}">
					<label for="radio1_2">営業課</label><input type="radio" id="radio1_2" name="radio1" value="営業課"
					th:checked="${dataModel.radio1== '営業課'}">
					<div th:if="${#fields.hasErrors('radio1')}" th:errors="*{radio1}"></div>
				</td>	
			</tr>
			<tr>
				<th>radio2</th>
				<td>
					<label for="radio2_1">HONDA</label><input type="radio" id="radio2_1" name="radio2" value="HONDA" 
					th:checked="${dataModel.radio2 == 'HONDA'}">
					<label for="radio2_2">KAWASAKI</label><input type="radio" id="radio2_2" name="radio2" value="KAWASAKI"
					th:checked="${dataModel.radio2== 'KAWASAKI'}">
					<div th:if="${#fields.hasErrors('radio2')}" th:errors="*{radio2}"></div>
				</td>	
			</tr>
			<tr>
				<th>check1</th>
				<td>
					<input type="checkbox" name="check1" value="チェックあり" th:checked="${dataModel.check1 == 'チェックあり'}">
				</td>	
			</tr>
			<tr>
				<th>check2</th>
				<td>
					<input type="checkbox" name="check2" value="選択されています" th:checked="${dataModel.check2 == '選択されています'}">
				</td>	
			</tr>
			<tr>
				<th>select1</th>
				<td>
					<select id="select1" name="select1">
						<option th:selected="${dataModel.select1 == 'みかん'}">みかん</option>
						<option th:selected="${dataModel.select1 == 'りんご'}">りんご</option>
						<option th:selected="${dataModel.select1 == 'ぶどう'}">ぶどう</option>
					</select>
					<div th:if="${#fields.hasErrors('select1')}" th:errors="*{select1}"></div>
				</td>	
			</tr>
			<tr>
				<th>select2</th>
				<td>
					<select id="select2" name="select2" multiple>
						<option th:if="${dataModel.select2 != null}" th:selected="${#strings.contains(dataModel.select2,'新潟県')}">新潟県</option>
						<option th:if="${dataModel.select2 == null}" >新潟県</option>
						<option th:if="${dataModel.select2 != null}" th:selected="${#strings.contains(dataModel.select2,'長野県')}">長野県</option>
						<option th:if="${dataModel.select2 == null}" >長野県</option>
						<option th:if="${dataModel.select2 != null}" th:selected="${#strings.contains(dataModel.select2,'島根県')}">島根県</option>
						<option th:if="${dataModel.select2 == null}" >島根県</option>
						<option th:if="${dataModel.select2 != null}" th:selected="${#strings.contains(dataModel.select2,'鹿児島県')}">鹿児島県</option>
						<option th:if="${dataModel.select2 == null}" >鹿児島県</option>
					</select>
					<div th:if="${#fields.hasErrors('select2')}" th:errors="*{select2}"></div>
				</td>	
			</tr>
		</table>
		<input type="submit" value="送信">
	</form>
	<p><a th:href="@{/jpa/menu04}">メニューページへ</a></p>
</body>


※複雑なのは複数選択可能なselect2で、dataModel.select2がnullの場合は#strings.containsがエラーになってしまう
　そのため、th:ifでnull判定をする




***************   Entity (lombok使用)  *********************

package p1.entities01;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

import lombok.Data;

@Entity
@Table(name="radio",schema="schema01")
@Data
public class Radio {
	
	@Id
	@Column(name = "id")
	@NotNull
	private Integer id;
	
	@NotEmpty
	@Column(name = "radio1",length=255)
	private String radio1;
	
	@NotEmpty
	@Column(name = "radio2",length=255)
	private String radio2;
	
	@NotEmpty
	@Column(name = "check1",length=255)
	private String check1;
	
	@NotEmpty
	@Column(name = "check2",length=255)
	private String check2;
	
	@NotEmpty
	@Column(name = "select1",length=255)
	private String select1;
	
	@NotEmpty
	@Column(name = "select2",length=255)
	private String select2;
}




*************   Repository  ******************

package p1.repositories01;

public interface Repository04 extends JpaRepository<Radio, Integer> {
	
	public Optional<Radio> findById(Integer id);
}




**********   Controller   ******************

package p1.jpa.controllers;

@Controller
public class JpaController04 {
	
	@Autowired
	Repository04 repository04;
	
	// メニュー表示用
	@RequestMapping(value="jpa/menu04")
	public ModelAndView menu(ModelAndView mav) {
		mav.setViewName("jpa/menu04");
		return mav;
	}
	
	// 新規データ登録ページ表示用
	@RequestMapping(value="jpa/dataUp04")
	public ModelAndView dataUp(@ModelAttribute("dataModel") Radio radio, ModelAndView mav) {
		mav.setViewName("jpa/dataUp04");  // データアップ用ページへ
		return mav;
	}
	
	// データリスト表示用
	@RequestMapping(value="jpa/dataList04",method=RequestMethod.GET)
	public ModelAndView get(@ModelAttribute Radio radio, ModelAndView mav) {
		mav.setViewName("jpa/dataList04");
		List<Radio> list = repository04.findAll();  
		mav.addObject("list",list);
		return mav;
	}
	
	// 新規データ登録用
	@RequestMapping(value="jpa/insert04",method=RequestMethod.POST)
	@Transactional(readOnly=false)
	public ModelAndView post(@ModelAttribute("dataModel")@Validated Radio radio, BindingResult result, ModelAndView mav) {
		
		if(result.hasErrors()) {
			mav.setViewName("jpa/dataUp04");
		}else {
			repository04.saveAndFlush(radio);
			mav.setViewName("redirect:/jpa/dataList04");
		}
		return mav;
	}
}




**********************   menu04   **************************

<body>
	<h2>Menu04</h2>
	<p><a th:href="@{/jpa/dataList04}">データリストページへ</a></p>
	<p><a th:href="@{/jpa/dataUp04}">データアップページへ</a></p>
</body>




****************    dataList04      **********************

th{ border: 1px solid; background-color: #B1F9D0}
td{ border: 1px solid; }
table{ border-collapse: collapse;}
</style>
</head>
<body>
	<h2>DataList04</h2>
	<table>
		<tr>
			<th>id</th>
			<th>radio1</th>
			<th>radio2</th>
			<th>check1</th>
			<th>check2</th>
			<th>select1</th>
			<th>select2</th>
		</tr>
		<tr th:each="obj : ${list}">
			<td th:text="${obj.id}"></td>
			<td th:text="${obj.radio1}"></td>
			<td th:text="${obj.radio2}"></td>
			<td th:text="${obj.check1}"></td>
			<td th:text="${obj.check2}"></td>
			<td th:text="${obj.select1}"></td>
			<td th:text="${obj.select2}"></td>
		</tr>
	</table>
	<p><a th:href="@{/jpa/menu04}">メニューページへ</a></p>
</body>






Template Mode 'HTML5' is deprecated. Using Template Mode 'HTML' instead  というエラーの対処

application.properties に以下を追記する

spring.thymeleaf.mode=HTML






アプリを再起動しなくてもテンプレートの変更を反映させるために、Thymeleafのキャッシュを無効にする
※ただし、本番では必ずtrueにすること

application.properties に以下を追記する

spring.thymeleaf.cache=false





ドキュメントルートを設定する

application.properties に以下を追記する

spring.thymeleaf.prefix=classpath:/page/


これでドキュメントルートは
src/main/resources/page/   になる
```