0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Thymleafのフォームで同じname属性が複数あった時の挙動

Posted at

背景

Thymleafを使ったフォーム作成でFormクラスのプロパティがListなどだったときに

  • th:field=""はどこに記述するのか
  • どうやってリクエストパラメータがクラスのプロパティに格納されるのか
    ちょっと迷ったので、どのように値が格納されるのか確認したので、備忘録として残す。

結論

同じname属性を持った入力欄が複数あった場合、
,区切りのデータにすることができるのなら、,区切りのデータになる

結論1 FormのプロパティがListなどの場合、要素として追加される
結論2 FormのプロパティがStringの場合、,区切りで結合されたString
結論3 FormのプロパティがIntegerの場合、1番最初に入力された値が格納される 

検証

簡単なフォームを作って、リクエストパラメータがフォームクラスのプロパティにどのように格納されるのか検証した。

準備

以下のような質問用のFormクラスを作成

QuestionForm.java
public class QuestionForm {
	
	private String name; // 名前を入力させる
	private List<String> hobbies; // 趣味を複数入力させる

	// getter, setterは省略

	@Override
	public String toString() {
		return "QuestionForm [name=" + name + ", hobbies=" + hobbies + "]";
	}
}

formの表示&送信されたフォームの確認をするコントローラを作成

QuestionController.java
@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.html
    <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スクリーンショット 2022-05-21 16.09.13.jpg
コンソールの出力↓
スクリーンショット 2022-05-21 16.07.20.jpg
name="hobbies"は複数あるが、FormクラスのプロパティがListであるため

結論2の検証

以下のように同じ入力欄を2つにして送信する
スクリーンショット 2022-05-21 16.14.29.jpg
コンソールの出力↓
スクリーンショット 2022-05-21 16.11.00.jpg
nameには"山田,太郎"が入った。1つめの入力欄と2つめの入力欄の内容は,で結合された。

結論3の検証

FormのnameプロパティをInteger型にしてみる
(結論2の検証の時と同様、名前の入力欄は2つ)

QuestionForm.java
public class QuestionForm {
	
	private  Integer name;
	private List<String> hobbies;
    // 以下、省略

最初に1を、次に2を入れて送信する

コンソールの出力↓
最初入れた1が格納された。
image.png

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?