# 🧩 Vol.11.7 `validate()` / `input` 結合戦略とUX設計   _Struts2におけるユーザー入力バリデーションと、画面遷移制御のベストプラクティス_

## 🔰 本記事のねらい

本記事では、Struts2における **`validate()` メソッド** と **`input` `result` タイプ** を使った「ユーザー入力のバリデーション＆フィードバック戦略」について、実務的な観点から解説します。

- `validate()` の仕組みとトリガーのタイミング
- `input` `result` による「バリデーションエラー時の画面遷移」
- バリデーション失敗時の入力保持＆エラーメッセージ表示のUX設計

---

## 🧪 1. `validate()` メソッドとは？

Struts2のアクションクラスで定義可能なメソッドで、**リクエスト処理前に入力検証を行う**ために使います。

```java
public class RegisterAction extends ActionSupport {
    private String username;
    private String password;

    public void validate() {
        if (username == null || username.isEmpty()) {
            addFieldError("username", "ユーザー名は必須です。");
        }
        if (password == null || password.length() < 6) {
            addFieldError("password", "パスワードは6文字以上で入力してください。");
        }
    }
}
```

### ✅ `validate()` の特徴

| 項目 | 内容 |
|------|------|
| 実行タイミング | `execute()` メソッドより前に自動実行 |
| バリデーション失敗時 | `input` `result` に遷移 |
| メッセージ登録 | `addFieldError()` or `addActionError()` を使用 |

---

## 🧭 2. `input` result でリトライ画面遷移

バリデーションに失敗した場合、Struts2は自動的に **`input` に対応する画面（通常は元の入力フォーム）に遷移**させます。

```xml
<action name="register" class="RegisterAction">
    <result name="success">register_success.jsp</result>
    <result name="input">register_form.jsp</result> <!-- バリデーションNG時に戻る -->
</action>
```

これにより、**再入力をユーザーに求める流れ**が自然に構成できます。

---

## 🎯 3. UX改善の観点：入力保持＆エラー表示

### 🌟 フィールドエラーの表示

`addFieldError("username", "...")` で登録されたエラーは、JSP上で `<s:fielderror>` タグを使って表示できます。

```jsp
<s:form action="register">
    <s:textfield name="username" label="ユーザー名"/>
    <s:password name="password" label="パスワード"/>
    <s:submit value="登録"/>
    <s:fielderror />
</s:form>
```

### 🌟 入力内容の保持

Struts2のバインディング機構により、**一度入力した内容は再描画時も自動でフォームに再反映**されるため、UXが非常に高まります。

---

## 🛠 4. Tips: 複数アクションでの入力検証分離

実務では以下のような「入力専用アクション」と「確認・登録用アクション」に処理を分離するパターンもあります：

```java
public class ConfirmInputAction extends ActionSupport {
    private String email;
    public void validate() {
        if (!email.contains("@")) {
            addFieldError("email", "メールアドレスの形式が正しくありません");
        }
    }
}
```

---

## 📝 5. よくある誤解と注意点

| 誤解 | 実際の挙動 |
|------|------------|
| `validate()` を定義しないとエラー処理できない？ | → XMLやアノテーションでも可能 |
| `input` は任意で設定する？ | → 未定義の場合はエラー画面に遷移する可能性があるので要定義 |
| `validate()` は任意？ | → はい、定義しないとバリデーション処理は一切行われません |

---

## 📘 まとめ：バリデーション × 画面遷移の設計を極めよう

Struts2における `validate()` + `input` `result` の組み合わせは、「サーバーサイドバリデーションの基礎」でありながら、UX設計において非常に重要な役割を果たします。

- `validate()` は入力検証の中心
- `input` は再入力画面として設計
- エラー表示と入力保持で再入力のストレスを軽減

---

## 📚 関連シリーズ記事

- 🧩 [🌟 Vol.11.4 総まとめ：Struts2自動バインディング完全理解ガイド _ParametersInterceptor × OGNL連携の仕組みと実践_](https://qiita.com/juehara-crypto/items/9a110434d7d2626aa149)
- 🧩 [🌟 Vol.11.5 総まとめ：Struts2 `struts.xml` 設定ファイル徹底理解ガイド _Struts2アーキテクチャの基盤となる `struts.xml` を“設定から設計へ”昇華させるためのベストガイド集_](https://qiita.com/juehara-crypto/items/5fcb05ec58b26051b36c)
- 🧩 [🧩 Vol.11.6 ActionSupport 活用大全：便利メソッドと国際化対応の完全理解 _Struts2ユーティリティクラスとi18n（国際化）対応を“実務視点”でマスターする_](https://qiita.com/juehara-crypto/items/bfbdc2203acac7ba3f19)
---

## 🧭 次回予告

🧩 Vol.11.8 アノテーションベース vs XML定義：開発スタイルと保守性のトレードオフを読み解く


---

### 🧭 関連記事（Vol.11.xxxシリーズ）
| 連番           | タイトル                                                  | 内容分類              |
| ------------ | ----------------------------------------------------- | ----------------- |
| [Vol.11.0](https://qiita.com/juehara-crypto/items/a0cc66893cb499a6e23a)     | Struts2が提供してくれる便利機能まとめ9選                              | 導入＆概要             |
| [Vol.11.1](https://qiita.com/juehara-crypto/items/0a584da537059dd43a7c)     | 自動注入とステートレスActionの仕組み                                 | フレームワーク内部理解       |
| [Vol.11.2](https://qiita.com/juehara-crypto/items/c69962826bb29639c351) | **UX改善に効く！アクション層設計と入力制御の極意（プロローグ）**                   | UX設計・アクション層総論     |
| [Vol.11.2.1](https://qiita.com/juehara-crypto/items/9ca115073e6f928c7f71)   | 【実践編】Struts2アクション層の役割と設計パターン（Command型 / UIアクション分離など）  | アクション設計パターン       |
| [Vol.11.2.2](https://qiita.com/juehara-crypto/items/88b7634a64b1ad564668)   | 【UX重視】戻るボタン・キャンセル処理の設計手法と「戻り先管理」のスマート実装               | 戻り先制御とUX設計        |
| [Vol.11.2.3](https://qiita.com/juehara-crypto/items/c5165c92a4366fd1962b)   | 【設計ノウハウ】多画面遷移時のパラメータ受け渡し・保持戦略（セッション vs hidden vs URL） | パラメータ多重管理         |
| [Vol.11.2.4](https://qiita.com/juehara-crypto/items/06162659215cca86de28)   | 【実践ガイド】ユーザー操作を考慮したアクション遷移設計（リダイレクト vs フォワードの使い分け）     | UX遷移設計／Result制御   |
| [Vol.11.2.5](https://qiita.com/juehara-crypto/items/b538b50eaa9c263a31bb)   | 【トラブル防止】アクション層の共通処理とメンテナブルなBaseAction設計               | アクション共通化／保守性      |
| [Vol.11.3](https://qiita.com/juehara-crypto/items/913de7c942a9242201e8)     | Struts2の defaultStack とは？Interceptorの中身を詳しく追ってみる      | Interceptor       |
| [Vol.11.3.2](https://qiita.com/juehara-crypto/items/ede8d3c2a9b147f6161e)     | 🔧 Vol.11.3.2 独自Interceptorの作り方と使い所 _Struts2のカスタマイズを“実践で使えるレベル”に一歩進めよう_     | Interceptor       |
| [Vol.11.4](https://qiita.com/juehara-crypto/items/253142d13fe5f604610f)     | 入門者のための「パラメータ自動バインディング」完全理解ガイド                        | 自動バインディング         |
| [Vol.Vol.11.4.1](https://qiita.com/juehara-crypto/items/4fd8ed2a8be317f6e1bd)     | 入門者のための自動バインディング実践パターン集                        | 自動バインディング         |
| [Vol.11.5](https://qiita.com/juehara-crypto/items/6ef7a87a54163d81a9ba)     | Struts2の構成理解が“実務レベル”へと進化する決定版         | 設定ファイル構造          |
| [Vol.11.5.1](https://qiita.com/juehara-crypto/items/df407b24101e92a02eab)     | Struts2の“画面遷移の全体像”を理解するためのマイルストーン記事         | 設定ファイル構造          |
| [Vol.11.6](https://qiita.com/juehara-crypto/items/bfbdc2203acac7ba3f19)     | ActionSupport の便利メソッドと国際化対応                           | ユーティリティ / i18n    | 
| [Vol.11.8](https://qiita.com/juehara-crypto/items/bb2b23612c22fa9bf50b)     | アノテーションベースの設定 vs XML定義の比較                             | 開発スタイルの違い         |
| [Vol.11.9](https://qiita.com/juehara-crypto/items/6163ad6c9308cc8dda6d)     | バリデーション完全解説（XML / アノテーション）                            | バリデーション（※Vol.8補完） |
| [Vol.11.10](https://qiita.com/juehara-crypto/items/207cb3d7f0a889c54df9)     | Struts2の「OGNL」ってなに？しくみと使い方をやさしく解説                     | 式言語OGNL解説         |
| [Vol.11.11](https://qiita.com/juehara-crypto/items/c313ea56f97984756c05)    | ModelDriven インターフェースの使いどころと注意点                        | Model駆動開発         |
| [Vol.11.12](https://qiita.com/juehara-crypto/items/de7a17d53e53d6466f17)    | SessionAware と RequestAware でセッション/リクエスト管理            | セッション管理           |
| [Vol.11.13](https://qiita.com/juehara-crypto/items/539bd5bae75a8e154753)    | Resultタイプ完全解説（dispatcher / redirect / stream など）      | 遷移パターン理解          |
| [Vol.11.14](https://qiita.com/juehara-crypto/items/142d9aa2c623c5eb70bc)    | Vol.11.14 ValueStackの中身を理解する – 画面とActionの橋渡し役                 | Action            |
| [Vol.11.15](https://qiita.com/juehara-crypto/items/84f024816d0cf2212cb6)    | Interceptorチェーンを自作してみよう（ログ / 認証フィルタ）                 | Interceptor            |
| [Vol.11.16](https://qiita.com/juehara-crypto/items/ff3ad75f9ee45fcd0f8f)    | エラー処理と例外ハンドリングの実践パターン                                 | ハンドリング設計          |
| [Vol.11.17](https://qiita.com/juehara-crypto/items/0d8d5101ff39b34b4704)    | Struts2でファイルアップロード機能を実装する方法                           | 実装系Tips           |
| [Vol.11.18](https://qiita.com/juehara-crypto/items/d93c8d9cee719997c068)    | 非同期通信（AJAX）とStruts2の連携方法                              | フロント連携編           |
| [Vol.11.19](https://qiita.com/juehara-crypto/items/dd6cf06d3100c9204d1f)    | セキュリティ対策（CSRF, XSS, パラメータ偽装）                              | セキュリティ対策           |
| [Vol.11.20](https://qiita.com/juehara-crypto/items/9442d9f4705f1c6c4da1)    | 複数フォームを安全に扱う！セッション管理と動的フォームの考え方                              | セッション管理           |
| [Vol.11.21](https://qiita.com/juehara-crypto/items/78eb217727b7c97f228a)    | Struts2でJSONを返す！REST API連携と非同期通信の基本設計                              | セッション管理           |
| [Vol.11.22](https://qiita.com/juehara-crypto/items/424155ee0e567a36b9a1)    | 本番環境構成とセキュリティ設計（Apache+Tomcat+Struts2連携）                             | 外部公開           |

---