Thymeleafのth:valueの使い方を解説!フォーム入力値を保持したり動的に表示する方法
生徒
「ThymeleafでHTMLフォームの入力値をJavaから表示させたいです。どうやってやるんですか?」
先生
「Thymeleafにはth:valueという便利な属性があるので、それを使ってJavaのデータをフォームに表示できます。」
生徒
「th:valueはどんな場面で役立ちますか?」
先生
「例えば、入力フォームで事前にユーザーの名前やメールアドレスをセットする時に役立ちますよ。」
1. th:valueとは?
th:valueは、Thymeleafのテンプレートエンジンで使われる属性で、HTMLフォームの入力フィールドにJavaの変数や値を動的に表示することができます。ユーザーの情報を事前にフォームに表示させたり、更新フォームで以前の入力データを保持したままにする場合などに使用します。実務の仕事でもよく使用するため、使い方をしっかりとマスターしましょう。
例えば、ユーザーのプロフィール編集画面で、名前やメールアドレスのフォームフィールドにユーザーの既存のデータを表示させることで、ユーザーは現在の情報を確認しながら必要な部分だけを編集できます。
2. th:valueの基本的な使い方
th:valueの基本的な使い方を見ていきましょう。以下のコードは、Javaのコントローラーからユーザーの名前をフォームに表示する例です。コントローラーで名前の情報をModelにセットし、それをth:valueで取り出して表示させます。
@Controller
public class UserController {
@GetMapping("/editProfile")
public String editProfile(Model model) {
model.addAttribute("userName", "山田太郎");
return "editProfile";
}
}
このように、コントローラーで渡された名前をeditProfile.htmlのフォームにth:valueを使って表示させます。
<input type="text" th:value="${userName}">
このコードを実行すると、画面に表示されたフォームには「山田太郎」がセットされます。ユーザーはこの値をそのまま確認、もしくは変更して送信することが可能です。このサンプルを理解することが大切です。
3. th:valueを使ったフォームの作成
次に、複数の入力フィールドにth:valueを活用して、ユーザーのプロフィール編集フォームを作成してみましょう。このフォームでは、名前とメールアドレスが事前に入力されている状態で表示され、ユーザーはそのまま情報を確認したり、必要に応じて変更できます。
@Controller
public class UserProfileController {
@GetMapping("/profile")
public String profilePage(Model model) {
model.addAttribute("userName", "山田太郎");
model.addAttribute("email", "taro@example.com");
return "profile";
}
}
対応するHTML側のコードです。th:valueを使ってユーザーのデータをフォームに反映させます。
<form action="/submitProfile" method="post">
<label>名前:</label>
<input type="text" th:value="${userName}">
<br>
<label>メールアドレス:</label>
<input type="email" th:value="${email}">
<br>
<button type="submit">更新</button>
</form>
この例では、名前とメールアドレスのフィールドにth:valueを使って、Javaで設定された値が事前に表示されます。これにより、ユーザーがプロフィールを簡単に確認し、必要に応じて更新ができるようになります。
4. th:valueの活用例と注意点
th:valueを使用することで、フォーム入力欄にサーバーサイドのデータを表示するのは便利ですが、特に注意が必要な場面もあります。例えば、ユーザーが一時的に入力して保存した情報を表示する場合や、エラーメッセージが出た際の再入力時に便利です。
ただし、重要なデータや個人情報を表示する際は、他のユーザーにデータが表示されないように、適切なセキュリティ対策を行いましょう。また、データが正しく取得できなかった場合に備えて、初期値やデフォルトメッセージを用意することも良い方法です。
5. サンプルコードで確認しよう
最後に、th:valueを使ってフォーム入力値を動的に表示させる例を確認してみましょう。以下のコードでは、Java側で設定したユーザー情報をフォームに反映させ、フォーム送信時にはその情報が保存されます。
@Controller
public class AccountController {
@GetMapping("/account")
public String accountPage(Model model) {
model.addAttribute("accountName", "Suzuki Ichiro");
model.addAttribute("accountEmail", "ichiro@example.com");
return "account";
}
}
<form action="/saveAccount" method="post">
<div>
<label>名前:</label>
<input type="text" th:value="${accountName}">
</div>
<div>
<label>メールアドレス:</label>
<input type="email" th:value="${accountEmail}">
</div>
<div>
<button type="submit">保存</button>
</div>
</form>
このようにth:valueを使えば、Javaで管理しているユーザーの情報をフォームに簡単に反映できます。初心者の方でも、Thymeleafのth:valueを使えば動的な入力フォームを簡単に実装できるでしょう。フォームに値を表示したいときや、既存のデータを更新する際には、このth:valueを活用してみてください。
6. th:valueとth:field/th:objectの違いと使い分け(入力値の自動バインド&保持)
フォームで入力値を保持したいなら、th:value単体よりth:object+th:fieldの組み合わせが便利です。th:fieldは、モデル上のフォームオブジェクトと双方向に結びつき、初期表示時は値を自動反映、送信後の再表示でもユーザー入力を自動で埋め戻します(HTMLのvalue・checked・selectedを適切に設定)。
@Controller
public class ProfileController {
// 入力フォーム用のDTO
public static class UserForm {
@NotBlank
private String name;
@Email
private String email;
// getter/setter 省略
}
@GetMapping("/profile/edit")
public String edit(Model model) {
UserForm form = new UserForm();
form.setName("山田太郎");
form.setEmail("taro@example.com");
model.addAttribute("userForm", form);
return "profile-edit";
}
}
<form th:object="${userForm}" action="/profile/save" method="post">
<label>名前</label>
<input type="text" th:field="*{name}" class="form-control">
<label class="mt-2">メール</label>
<input type="email" th:field="*{email}" class="form-control">
<button type="submit" class="btn btn-primary mt-3">保存</button>
</form>
既存のテンプレートでth:value="${userName}"のように1項目だけ差し込みたい場合はth:valueでOK。フォーム全体を一貫してバインドしたい場合はth:fieldへ移行すると、チェックボックスやセレクトの選択状態も自動管理され、保守性・再利用性が向上します。
なお、値がnullのときにデフォルト表示をしたいなら、Elvis演算子で簡潔に書けます:
th:value="${userForm.nickname} ?: '未設定'"
7. バリデーションエラー時に入力値を保持しつつエラーメッセージを表示する(Spring Validation+th:errors)
「入力エラーで戻ったら値が消えた…」という悩みは、@Valid+BindingResultとth:fieldで解決できます。エラー時も入力値を保持し、該当フィールドの直下にエラーメッセージを表示できます。SEOキーワード的にも「Thymeleaf th:value 入力値 保持」「バリデーション 再表示」は重要です。
@Controller
public class ProfileSaveController {
@PostMapping("/profile/save")
public String save(@Valid @ModelAttribute("userForm") ProfileController.UserForm form,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
// エラー時:同じテンプレートを再表示(入力値は保持される)
return "profile-edit";
}
// 正常時の保存処理 … 省略
return "redirect:/profile/edit?success";
}
}
<form th:object="${userForm}" action="/profile/save" method="post">
<div class="mb-2">
<label>名前</label>
<input type="text" th:field="*{name}" class="form-control"
th:classappend="${#fields.hasErrors('name')} ? ' is-invalid' : ''">
<div class="invalid-feedback" th:if="${#fields.hasErrors('name')}"
th:errors="*{name}">入力エラー</div>
</div>
<div class="mb-2">
<label>メール</label>
<input type="email" th:field="*{email}" class="form-control"
th:classappend="${#fields.hasErrors('email')} ? ' is-invalid' : ''">
<div class="invalid-feedback" th:if="${#fields.hasErrors('email')}"
th:errors="*{email}">入力エラー</div>
</div>
<button type="submit" class="btn btn-primary">送信</button>
</form>
これで、サーバー側の検証に失敗しても、ユーザーが入力した値は保持され、どこを直せば良いかが即座にわかります。既存のth:valueのみの実装からでも、段階的にth:object+th:fieldへ移行すると、フォームの体験と実装の見通しが大きく改善します。
まとめ
ここまで、Thymeleafのth:valueを活用してフォームに動的なデータを表示する方法について学んできました。th:valueは、HTMLフォームの入力欄にJavaのデータを埋め込み、ユーザーの情報を事前に表示するのに便利な属性です。例えば、プロフィール編集や登録情報の確認ページでは、th:valueを使って既存のデータを簡単に表示させることができます。
th:valueを使ったデータの埋め込みは、フォームの利便性を向上させ、ユーザーがよりスムーズに情報を確認・編集できるようにします。また、更新フォームでModelを利用してユーザーのデータを保持し、入力項目を再度表示させることで、エラー後の再入力などにも役立ちます。
th:valueを活用したフォーム作成の基本的な流れは、コントローラーでデータをModelに格納し、HTMLのth:value属性で表示させるというシンプルな構造です。これにより、JavaとHTMLの連携がスムーズになり、特にユーザーごとに異なるデータを扱う場面では効果的に機能します。
以下に再度、ユーザーのプロフィールを編集する際のサンプルコードを示します。Modelを利用してコントローラーからユーザー情報を渡し、フォームにデフォルト値として表示させます。この手法を理解することで、他のデータフィールドにも応用しやすくなります。
@Controller
public class ProfileController {
@GetMapping("/editProfile")
public String editProfile(Model model) {
model.addAttribute("userName", "田中花子");
model.addAttribute("email", "hanako@example.com");
return "editProfile";
}
}
<form action="/updateProfile" method="post">
<label>名前:</label>
<input type="text" th:value="${userName}">
<br>
<label>メールアドレス:</label>
<input type="email" th:value="${email}">
<br>
<button type="submit">更新</button>
</form>
このサンプルコードのように、Modelとth:valueを連携させることで、ユーザーのプロファイル情報をフォームに反映させることができます。th:valueは、他の入力フィールドや選択リストにも適用できるため、さまざまなフォームにおいてデータの表示や更新に役立つでしょう。
また、セキュリティ面でも重要なデータを扱う場合、他ユーザーとデータが共有されないようにアクセス制限や非表示設定を適切に行うことも必要です。th:valueを使う際には、こうしたセキュリティにも配慮し、ユーザー体験を損なわない形でフォームの利便性を高めていきましょう。
生徒
「先生、今日学んだth:valueの使い方ですが、どんな場面で役立ちそうですか?」
先生
「とてもいい質問だね。例えば、ユーザーのプロフィール編集や設定ページで現在の情報をフォームに表示させるのに便利だよ。他にも、カート機能で注文内容を確認したりする場合にも応用できるんだ。」
生徒
「なるほど!あと、フォーム送信時にエラーが出たときに、入力値が保持されるので、再入力の手間が減りますね。」
先生
「その通りだよ。再入力の手間が省けることでユーザー体験が良くなるし、データの一貫性も保たれるね。今回学んだ方法は、他のプロジェクトにも応用しやすいから、しっかり覚えておくといいよ。」
生徒
「ありがとうございます、先生。これでプロフィール編集ページも作れる自信がつきました!」
先生
「良かった!困ったときはまた聞いてね。th:valueはしっかりと使いこなせるようになると、動的なフォームが簡単に作れるから、他の機能でもどんどん試してみよう!」