😊

【Spring boot】 バリデーション付きのカテゴリ作成処理(POST)を実装する

に公開

📌 はじめに

前回の記事では、@Controller@ModelAttribute を使って「カテゴリ作成フォームの表示」までを行いました。
今回はその続きを扱います。

カテゴリを実際に作成(POST)し、バリデーション付きで保存する処理を作っていきます。


🎯 実現すること

  • POSTメソッドでカテゴリを新規登録
  • 入力されたカテゴリ名に対して**バリデーション(空欄NG/文字数制限)**を行う
  • エラーがあった場合は、フォーム画面に戻してメッセージを表示


🧩 コントローラ:POSTメソッドの実装

@PostMapping
public String create(@ModelAttribute @Valid Category category, BindingResult result) {
    if (result.hasErrors()) return "category/form";
    service.save(category);
    return "redirect:/categories";
}

🔍 補足ポイント

アノテーション 役割
@ModelAttribute:フォームから送られた値を Category に自動バインド
@ValidCategory に対してバリデーションを実行
BindingResult:バリデーション結果を保持。エラーがあれば hasErrors() が true に

🧾 エンティティのバリデーション指定

バリデーションとは、画面から入力された値がルールに合っているかチェックする仕組みです。
Spring Bootでは、エンティティのフィールドにアノテーションを付けることで簡単にバリデーションを指定できます。

✅ 例:Category エンティティにバリデーションを追加

@Entity
public class Category {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	
	/** スキルID */
	private Long skillId;
	
	/** スキル名 */
	@NotBlank(message = "カテゴリ名は必須です")
	@Size(max = 30, message = "カテゴリ名は30文字以内で入力してください")
	private String name;
	// getter / setter
}

@Id:エンティティの主キー(ID)を示すアノテーション。DBで言う「PRIMARY KEY」。
GeneratedValue(strategy = GenerationType.IDENTITY):IDを自動採番する指定。IDENTITY はDB側に自動で任せる方式(MySQLのAUTO_INCREMENTなど)
@NotBlank:空文字・空白文字を許さない(null も不可)
@Size(max=30):文字数の上限を設定(max=30文字)

``

✅ 依存ライブラリの追加(重要)

バリデーションを有効にするには、spring-boot-starter-validationpom.xml に追加する必要があります。

<!-- skill-log-domain/pom.xml などEntityを含むモジュールに追加 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
  • @Valid は自動でバリデーションを走らせるが、その仕組み自体が spring-boot-starter-validation によって提供されている
  • 依存がないとアノテーションを付けても無視される
    ※追加後はプロジェクトを再ビルドしてください。

🖼️ フォーム画面でのエラー表示

テンプレートは下記。

<form th:object="${category}" method="post" th:action="@{/categories}">
  <div class="mb-3">
    <label class="form-label">カテゴリ名:</label>
    <input type="text" th:field="*{name}" class="form-control" />
    
    <div th:if="${#fields.hasErrors('name')}" class="text-danger">
      <p th:errors="*{name}">エラー表示</p>
    </div>
  </div>

  <button type="submit" class="btn btn-primary">保存</button>
</form>

実際の表示イメージ↓

📚 実行の流れ(図イメージ)

📝 まとめ

@Valid と BindingResult をセットで使うことで、バリデーション付きフォーム処理が可能になります。

入力エラー時はそのまま同じフォームに戻して、修正を促します。

Discussion