Springフォーム入力からControllerへ!初心者でもわかる入力データの受け取り方
新人
「Springでユーザーが入力した値を受け取るにはどうすればいいんですか?フォーム入力の仕組みがまだよくわからなくて…」
先輩
「それは大事なところだね。まずは、HTMLのformタグで入力画面を作って、そのデータをSpringの@Controllerで受け取るという流れになるよ。」
新人
「なるほど…でも、具体的にはどうやって連携させるんですか?」
先輩
「じゃあ、まずはフォームとControllerの連携方法を順番に見ていこうか!」
1. フォームからデータを受け取る基本的な仕組み
Springでは、ユーザーが入力した情報をサーバーに送るために、HTML formとSpring Controllerを組み合わせて使います。これがいわゆる「Spring フォーム入力」の基本構成です。
まずは、名前とメールアドレスを入力する簡単なHTMLフォームの例を見てみましょう。
<form action="/submit" method="post">
<label for="name">名前:</label>
<input type="text" id="name" name="name">
<br>
<label for="email">メールアドレス:</label>
<input type="email" id="email" name="email">
<br>
<button type="submit">送信</button>
</form>
このformは、ユーザーが入力した「名前」と「メールアドレス」を、/submitというURLにPOST形式で送信します。
ポイントは、name属性の値が、Springの@Controller側で受け取るときのキーになるということです。このHTMLとControllerが連携することで、スムーズにデータを処理できます。
このように、「Spring フォーム入力」の基本は、formタグとControllerの連携にあります。
2. @Controllerを使った入力受け取りの方法
次は、Springの@Controllerを使って、フォームから送られたデータを受け取る方法を紹介します。
Springでは@RestControllerではなく、通常の@Controllerを使うことで、HTML画面の表示を行いながらデータを受け取ることができます。
以下のコードは、フォームから送信された名前とメールアドレスを受け取り、それを画面に渡すシンプルな例です。
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.ui.Model;
@Controller
public class FormController {
@PostMapping("/submit")
public String handleForm(
@RequestParam("name") String name,
@RequestParam("email") String email,
Model model
) {
model.addAttribute("name", name);
model.addAttribute("email", email);
return "result";
}
}
@PostMappingで指定した/submitは、先ほどHTMLで書いたaction="/submit"と一致させる必要があります。
また、@RequestParamでフォームのname属性の値を受け取り、それをModelに追加しています。これによって、別のHTML画面に渡して表示できるようになります。
このように、「Spring Controller 入門」の基本は、@Controllerと@RequestParamを正しく使って、フォーム入力を受け取ることにあります。
3. 受け取ったデータをEntityにマッピングする方法
Springでは、フォームから受け取った入力値をそのまま変数として受け取る方法もありますが、より実践的な開発では「エンティティ(Entity)」というクラスにデータをまとめて扱うのが一般的です。
このやり方を知っておくことで、「フォームからEntityへマッピング」する方法が自然に理解でき、後のデータベース保存などにもスムーズにつながります。
たとえば、以下のようなフォームがあったとします。
<form action="/register" method="post">
<label for="name">名前:</label>
<input type="text" id="name" name="name">
<br>
<label for="email">メールアドレス:</label>
<input type="email" id="email" name="email">
<br>
<button type="submit">登録</button>
</form>
このフォームから送られたデータを、Springの@ModelAttributeを使ってエンティティにマッピングするには、以下のようなコントローラクラスにします。
@PostMapping("/register")
public String register(@ModelAttribute("user") User user, Model model) {
model.addAttribute("user", user);
return "confirm";
}
@ModelAttributeを使うことで、HTMLのフォームから送られてきた値が、自動的にUserクラスのフィールドにマッピングされます。これが「Spring Entity 作り方」の基礎になります。
4. フィールドとフォームのname属性の対応
Springで「フォームからEntityへマッピング」する際にもっとも大事なのが、フォームのname属性とエンティティクラスのフィールド名が一致していることです。
たとえば、次のようなUserクラスがあるとします。
public class User {
private String name;
private String email;
// GetterとSetter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
このUserクラスに対して、HTML側のフォームでname="name"やname="email"と指定しておけば、自動的に対応するSetterメソッドが呼び出されます。
そのため、HTMLフォームのname属性とJavaクラスのフィールド名を一致させることが、正しくマッピングされるためのポイントになります。
5. Entityクラスの作成とバリデーション
フォーム入力を受け取るEntity(エンティティ)クラスを作成する際は、必要に応じてバリデーション(入力チェック)を追加することもできます。
以下は、@NotEmptyや@Emailといったアノテーションを使って、空欄チェックやメール形式チェックを行うUserクラスの例です。
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
public class User {
@NotEmpty(message = "名前を入力してください")
private String name;
@NotEmpty(message = "メールアドレスを入力してください")
@Email(message = "正しいメールアドレスを入力してください")
private String email;
// GetterとSetter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
このようにアノテーションを追加することで、入力されたデータが正しいかどうかをチェックできるようになります。
次に、Controller側で@Validを使ってバリデーションを有効にします。
import org.springframework.validation.BindingResult;
import jakarta.validation.Valid;
@PostMapping("/register")
public String register(@Valid @ModelAttribute("user") User user,
BindingResult result,
Model model) {
if (result.hasErrors()) {
return "form";
}
model.addAttribute("user", user);
return "confirm";
}
@Validをつけることでバリデーションが実行され、エラーがある場合はresult.hasErrors()で検出されます。エラーがあれば入力フォームに戻り、なければ確認画面へ進むという流れです。
このように、Springでは「Entity 作り方」をしっかり理解し、バリデーションと組み合わせることで、より安全で使いやすいアプリケーションを作ることができます。
6. EntityをRepositoryを使ってDBに保存する方法
入力されたデータをEntityにマッピングできたら、次はそれをデータベースに保存する処理を行います。「Spring DB保存」を行うためには、まずEntityを管理するためのRepositoryインターフェースを作成します。
Springでは、JpaRepositoryを継承するだけで基本的な保存処理が自動で実装されるようになります。以下はその例です。
package com.example.demo.repository;
import com.example.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
このようにJpaRepositoryを使えば、saveやfindAllなどの便利なメソッドが最初から使えるようになります。
次に、実際の保存処理はControllerやServiceクラスの中で呼び出します。今回はControllerで直接呼び出す形にします。
@Controller
public class UserController {
private final UserRepository userRepository;
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@PostMapping("/register")
public String register(@Valid @ModelAttribute("user") User user,
BindingResult result,
Model model) {
if (result.hasErrors()) {
return "form";
}
userRepository.save(user); // データベースへ保存
return "redirect:/success";
}
}
このようにuserRepository.save(user)を呼び出すだけで、エンティティがデータベースに保存されます。これが「Repository 保存方法」の基本です。
7. 成功時の画面遷移やリダイレクトの考え方
データの保存が成功した後にそのまま同じURLを再読み込みしてしまうと、同じデータが再度送信されてしまう可能性があります。これを防ぐために「リダイレクト」を使います。
return "redirect:/success";とすることで、画面遷移ではなくURLを再指定して次の画面へ移動させます。
このようにリダイレクトを活用することで、データの二重送信を防ぎつつ、スムーズに画面遷移させることができます。次は、遷移先となるsuccess.htmlの表示用テンプレートの一例です。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>登録完了</title>
<meta charset="UTF-8">
</head>
<body>
<h2>登録が完了しました!</h2>
</body>
</html>
このテンプレートをtemplates/success.htmlに設置すれば、登録完了後にユーザーに確認画面を表示できます。
8. よくあるエラーとその対処法
最後に、Springで「フォーム入力 → Entity → DB保存」の処理を行う中で、初心者がよく直面するエラーとその解決方法を紹介します。
① バインドエラー(Binding Error)
フォームとエンティティクラスのフィールド名が一致していないと、バインドエラーになります。たとえば、フォームでname="fullName"としているのに、エンティティ側にfullNameというフィールドがない場合です。
対処法:フォームのname属性と、エンティティクラスのフィールド名は完全に一致させましょう。
② バリデーションエラー
@NotEmptyや@Emailなどで定義された条件に一致しないと、バリデーションエラーになります。たとえば、空の文字列や不正な形式のメールアドレスなどが原因です。
対処法:BindingResultを使ってhasErrors()でチェックし、エラーがあればフォーム画面に戻す処理を必ず入れましょう。
③ save時のエラー(エンティティが不完全)
バリデーションが正しく行われていない場合、save()の実行時にNULL制約エラーや型不一致のエラーが発生することがあります。
対処法:エンティティのフィールドには正しい型と制約を設定し、バリデーションもあわせて行うようにしましょう。
④ データベース接続エラー
application.propertiesの記述ミスや、依存関係の不足により、データベース接続に失敗するケースもあります。
対処法:Pleiades上でSpring Bootプロジェクトを作成する際に、Spring Data JPAとH2 DatabaseやMySQL Driverなどの依存関係を必ず選択しましょう。