背景
Thymleafを使ったフォーム作成でFormクラスのプロパティがListなどだったときに
-
th:field=""
はどこに記述するのか - どうやってリクエストパラメータがクラスのプロパティに格納されるのか
ちょっと迷ったので、どのように値が格納されるのか確認したので、備忘録として残す。
結論
同じname属性を持った入力欄が複数あった場合、
,
区切りのデータにすることができるのなら、,
区切りのデータになる
結論1 FormのプロパティがListなどの場合、要素として追加される
結論2 FormのプロパティがStringの場合、,
区切りで結合されたString
結論3 FormのプロパティがIntegerの場合、1番最初に入力された値が格納される
検証
簡単なフォームを作って、リクエストパラメータがフォームクラスのプロパティにどのように格納されるのか検証した。
準備
以下のような質問用のFormクラスを作成
public class QuestionForm {
private String name; // 名前を入力させる
private List<String> hobbies; // 趣味を複数入力させる
// getter, setterは省略
@Override
public String toString() {
return "QuestionForm [name=" + name + ", hobbies=" + hobbies + "]";
}
}
formの表示&送信されたフォームの確認をするコントローラを作成
@Controller
@RequestMapping("/form")
public class QuestionController {
@RequestMapping("")
public String index(QuestionForm form, Model model) {
// 好きな趣味の選択肢を作成
List<String> hobbyList = new ArrayList<>();
hobbyList.add("ランニング");
hobbyList.add("映画鑑賞");
hobbyList.add("フットサル");
hobbyList.add("散歩");
// 選択肢はリクエストスコープに入れてHTMLから読み込めるようにしておく
model.addAttribute("hobbyList",hobbyList);
return "form.html";
}
// 受け取った値をコンソールで確認する(ページ遷移先は適当に設定)
@RequestMapping("/receive")
public String receive(QuestionForm form) {
System.out.println(form);
System.out.println("nameの型 : " + form.getName().getClass().getSimpleName());
System.out.println("hobbiesの型 : " + form.getHobbies().getClass().getSimpleName());
return "output.html";
}
HTMLは以下のように作成
(簡単のため、labelとinputの紐付けなどは省略)
<form th:action="@{/form/receive}" th:object="${questionForm}" method="post">
<label>名前 : </label>
<input type="text" th:field="*{name}" /><br />
<div>
趣味 : <br />
<!-- リクエストスコープ内のhobbyLisをループで選択肢を表示 -->
<div th:each="hobby : ${hobbyList}">
<input type="checkbox" th:field="*{hobbies}" th:value="${hobby}"/>
<label th:text="${hobby}" ></label>
</div>
</div>
<button type="submit">送信</button>
</form>
検証項目
ここではQuestionController.javaに記述したとおり、
- フォームのnameプロパティの型
- hobbiesプロパティの型
を確認している。
結論1の検証
生成されるHTML
コンソールの出力↓
name="hobbies"
は複数あるが、FormクラスのプロパティがListであるため
結論2の検証
以下のように同じ入力欄を2つにして送信する
コンソールの出力↓
nameには"山田,太郎"が入った。1つめの入力欄と2つめの入力欄の内容は,
で結合された。
結論3の検証
FormのnameプロパティをInteger型にしてみる
(結論2の検証の時と同様、名前の入力欄は2つ)
public class QuestionForm {
private Integer name;
private List<String> hobbies;
// 以下、省略