📘 Vol.9.8：【Struts2】独自バリデータ作成編 〜 カスタムFieldValidatorで共通バリデーションを再利用しよう 〜

### 🧭 はじめに
Struts2では `required` や `regex` などの標準バリデータを使って
XMLやJavaでバリデーションを簡単に定義できます。

しかし、以下のような ***複雑なチェックや複数画面での使い回し*** をしたい場合、
***「独自バリデータ（Custom FieldValidator）」*** を作成するのがベストです。

---

### ✅ 独自バリデータが必要になる場面
| パターン                        | 解説                            |
| --------------------------- | ----------------------------- |
| 特定形式の文字列チェック（例：社員番号、電話番号など） | 他の画面でも使い回したい                  |
| 条件付きチェック（ある値のときだけ制限をかけたい）   | `validate()` だけだと画面ごとに書く必要がある |
| 画面ごとに同じルールを書いていて保守がつらい      | バリデーション処理を共通化したい              |

---

### 🛠 カスタムバリデータ作成の流れ
- 1.`FieldValidatorSupport` を継承したJavaクラスを作る

- 2.`validate()` メソッド内でロジックを記述

- 3.`validators.xml` または -`validation.xml` で定義して使う

---

### ✍ 実装例：AlphanumericValidator.java（英数字チェック）

### ① Javaクラスの作成
```java
public class AlphanumericValidator extends FieldValidatorSupport {
    @Override
    public void validate(Object object) throws ValidationException {
        String fieldName = getFieldName();
        String value = (String) getFieldValue(fieldName, object);

        if (value != null && !value.matches("^[a-zA-Z0-9]+$")) {
            addFieldError(fieldName, object);
        }
    }
}

```

---

### ② validators.xml に登録

`src/validators.xml`（共通で使えるように設定）
```xml
<!DOCTYPE validators PUBLIC
    "-//OpenSymphony Group//XWork Validator Config 1.0//EN"
    "http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd">

<validators>
    <validator name="alphanumeric" class="com.company.bulletinboard.validator.AlphanumericValidator"/>
</validators>

```

---

### ③ 使用側の validation.xml にて呼び出し
```xml
<field name="userId">
    <field-validator type="alphanumeric">
        <message>ユーザーIDは英数字のみで入力してください。</message>
    </field-validator>
</field>
```

---

### 💡 使い回しのTips

| ポイント                           | 解説                              |
| ------------------------------ | ------------------------------- |
| `validators.xml` に登録すれば全体で利用可能 | どのActionでもtype="xxx" で呼び出せる     |
| 複数のバリデータに共通ロジックがあるなら基底クラス化もあり  | DRY原則を意識して構成可能                  |
| テストしやすい構造にしておくと将来メンテしやすい       | 単体テスト or Validator単体のJUnit化も視野に |


---

### 🎯 まとめ
- カスタムバリデータを使えば、複雑なチェックや再利用性の高いルールも1つに集約できる

- XMLベースで呼び出せるため、従来の`validate()`との併用もOK

- `validators.xml` で一元管理することで、プロジェクト全体で使える資産に

### [🧭 次回予告：Vol.9.9](https://qiita.com/juehara-crypto/items/6df87d22d07818df5166)
次回は、**バリデーション処理の「単体テスト」** について解説します！

- `validate()` のテスト

- 独自バリデータの`JUnitテスト`

- エラー発生時の挙動確認（input 遷移、メッセージ表示）

Struts2におけるバリデーションの品質を保つためのヒントをお届けします！

---

### ✨ シリーズまとめ（Vol.9.x バリデーション編）

- [✅ Vol.9.0：入力バリデーションと型変換の世界へ](https://qiita.com/juehara-crypto/items/263e0eb599be73681b0f)

- [✅ Vol.9.1：validate()の基本と addFieldError]()

- [✅ Vol.9.2：Struts2実装編（input遷移・fielderror活用）](https://qiita.com/juehara-crypto/items/44fd5012bfbc809d352a)

- [✅ Vol.9.3：XMLバリデーション定義](https://qiita.com/juehara-crypto/items/fd6881d2c54de07b3ae4)

- [✅ Vol.9.4：条件付きチェック・複数フィールド連動チェック](https://qiita.com/juehara-crypto/items/c82203f583b2712be395)

- [✅ Vol.9.5：エラーメッセージ表示のデザインとUX](https://qiita.com/juehara-crypto/items/c44fae5980a5c9b40312)

- [✅ Vol.9.6：i18n対応・バリデーションエラーの多言語表示で保守性UP](https://qiita.com/juehara-crypto/items/de18b174f1740f9b3646)

- [✅ Vol.9.7：入力値の保持＆初期値再表示編](https://qiita.com/juehara-crypto/items/793e85ad47b981d6fbae)
---

## 🔎 Vol.9系で扱うトピック

| 回   | テーマ                                         | 内容の一部紹介                              |
|------|----------------------------------------------|--------------------------------------------|
| [9.1](https://qiita.com/juehara-crypto/items/a67976acd60430fa0da6)  | `validate()`メソッドの基本                    | Struts2標準の入力チェック基礎              |
| [9.2](https://qiita.com/juehara-crypto/items/44fd5012bfbc809d352a)  | `@Validations` アノテーション活用             | 宣言的バリデーション設計                   |
| [9.3](https://qiita.com/juehara-crypto/items/fd6881d2c54de07b3ae4)  | `validation.xml` 外部定義でのバリデーション   | 大規模PJでのメンテナンス性                 |
| [9.4](https://qiita.com/juehara-crypto/items/c82203f583b2712be395)  | `conversion.properties` と型変換              | 日付/数値/Enum変換の実務対応               |
| [9.5](https://qiita.com/juehara-crypto/items/c44fae5980a5c9b40312)  | 入力エラー時のメッセージ制御                  | `addFieldError()` / メッセージキー運用     |
| [9.6](https://qiita.com/juehara-crypto/items/de18b174f1740f9b3646)  | バリデーション共通化                         | 共通部品によるDRY設計                      |
| [9.7](https://qiita.com/juehara-crypto/items/793e85ad47b981d6fbae)  | サーバサイドとクライアントサイドの協調        | jQueryやHTML5との併用戦略                  |
| [9.8](https://qiita.com/juehara-crypto/items/b11017ca621d94599f72)  | 実務シナリオでのバリデーション総仕上げ       | 会員登録/投稿処理などの実例適用           |
| [9.9](https://qiita.com/juehara-crypto/items/6df87d22d07818df5166)  | バリデーション処理の単体テスト編       | validate()／独自バリデータ／input遷移の検証を網羅的に |
| [9.10](https://qiita.com/juehara-crypto/items/6c042593898aa598cba4)  | エラー表示のUIデザイン編        | 視認性・操作性を高める実践テクニック |
| [9.11](https://qiita.com/juehara-crypto/items/7d33c9cd812b37153c12)  | Ajax×バリデーション連携編        | クライアント×サーバーで UX＆保守性を両立するハイブリッド構成 |



--