Loading
  • LIGHT

  • DARK

ROUTE

ルートゼロの
アクティビティ

Spring Boot バリデーション入門|MVC統合とカスタムアノテーション実践例

2

1. はじめに


2. バリデーションの基本概念と日常の例え

2.1 バリデーションとは?

2.2 郵便局での荷物送付に例える


3. Spring Bootにおける基本的なバリデーションの実装

3.1 ユーザー情報クラスの作成

// src/main/java/com/example/demo/model/User.java
package com.example.demo.model;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class User {

    @NotNull(message = "名前は必須です")
    @Size(min = 1, max = 100, message = "名前は1文字以上100文字以内で入力してください")
    private String name;

    @NotNull(message = "メールアドレスは必須です")
    @Email(message = "メールアドレスの形式が正しくありません")
    private String email;

    // ゲッター・セッター
    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;
    }
}

3.2 REST APIでのバリデーション

// src/main/java/com/example/demo/controller/UserController.java
package com.example.demo.controller;

import com.example.demo.model.User;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @PostMapping("/addUser")
    public String addUser(@Validated @RequestBody User user) {
        // バリデーションが成功すればユーザー追加処理を実行
        return "ユーザーが正常に追加されました";
    }
}

4. MVCモデルにおけるカスタムバリデーション

4.1 カスタムバリデーションが必要な理由

4.2 カスタムバリデーションの全体の流れ


4.3 カスタムアノテーションの定義

// src/main/java/com/example/demo/validation/ValidDate.java
package com.example.demo.validation;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Documented
@Constraint(validatedBy = CustomDateValidator.class)
@Target({ FIELD })
@Retention(RUNTIME)
public @interface ValidDate {
    String message() default "日付はYYYY-MM-DD形式で入力してください";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

4.4 バリデータクラスの実装

// src/main/java/com/example/demo/validation/CustomDateValidator.java
package com.example.demo.validation;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class CustomDateValidator implements ConstraintValidator<ValidDate, String> {

    @Override
    public void initialize(ValidDate constraintAnnotation) {
        // 必要な初期化処理があればここで実施(今回は不要なため空実装)
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        // nullチェック(nullは必須チェックは他のアノテーションで行う前提)
        if (value == null) {
            return true;
        }
        // 正規表現で「YYYY-MM-DD」形式をチェックする
        return value.matches("\d{4}-\d{2}-\d{2}");
    }
}

4.5 MVCプロジェクトでの統合例

// src/main/java/com/example/demo/form/EventForm.java
package com.example.demo.form;

import com.example.demo.validation.ValidDate;
import javax.validation.constraints.NotNull;

public class EventForm {

    @NotNull(message = "日付は必須項目です")
    @ValidDate
    private String eventDate;

    private String eventName; // イベント名など他の項目も追加可能

    // ゲッター・セッター
    public String getEventDate() {
        return eventDate;
    }
    public void setEventDate(String eventDate) {
        this.eventDate = eventDate;
    }
    public String getEventName() {
        return eventName;
    }
    public void setEventName(String eventName) {
        this.eventName = eventName;
    }
}
// src/main/java/com/example/demo/controller/EventController.java
package com.example.demo.controller;

import com.example.demo.form.EventForm;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class EventController {

    @GetMapping("/event/register")
    public String showEventForm(Model model) {
        model.addAttribute("eventForm", new EventForm());
        return "eventForm"; // View名(テンプレートファイル)
    }

    @PostMapping("/event/register")
    public String registerEvent(@Validated EventForm eventForm, BindingResult bindingResult, Model model) {
        if (bindingResult.hasErrors()) {
            // バリデーションエラーがあれば再度フォーム画面に戻す
            return "eventForm";
        }
        // 正常処理(例:DB保存やサービス層への委譲)
        model.addAttribute("message", "イベント登録が完了しました");
        return "eventSuccess";
    }
}

5. プロジェクトのフォルダ構成

demo-project/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── example/
│   │   │           └── demo/
│   │   │               ├── DemoApplication.java         // Spring Bootアプリケーションのエントリーポイント
│   │   │               ├── controller/
│   │   │               │   └── EventController.java       // コントローラークラス
│   │   │               ├── form/
│   │   │               │   └── EventForm.java             // フォームオブジェクト
│   │   │               ├── model/
│   │   │               │   └── User.java                  // ユーザーエンティティ(例)
│   │   │               └── validation/
│   │   │                   ├── ValidDate.java             // カスタムアノテーション
│   │   │                   └── CustomDateValidator.java     // バリデータクラス
│   │   └── resources/
│   │       ├── application.properties                   // アプリケーション設定ファイル
│   │       └── templates/
│   │           ├── eventForm.html                       // イベント登録フォームのView
│   │           └── eventSuccess.html                    // 成功画面のView
│   └── test/
│       └── java/
│           └── com/
│               └── example/
│                   └── demo/
│                       └── DemoApplicationTests.java      // テストクラス
└── pom.xml                                             // Mavenプロジェクトの場合のビルド設定

6. よくあるトラブルと改善ポイント

6.1 アノテーションの組み合わせ

6.2 エラーハンドリングの整備

6.3 カスタムバリデーションのデバッグ


7. まとめと次のステップ

7.1 まとめ

7.2 次のステップ


最後に

【外部リンク】

【内部リンク】

RANKINGranking-icon

LATEST POSTS

もっとルートゼロを知りたいなら

DISCOVER MORE