🔍 Vol.11.3 Struts2の defaultStack とは？Interceptorの中身を詳しく追ってみる

> **Struts2の画面遷移は、Interceptorがすべてを握っている。**  
> 「defaultStackって何？」「独自Interceptorってどう動くの？」という疑問に答える、**Interceptor完全理解の第一歩**。

---

## 🧭 はじめに：defaultStackの正体とは？

Struts2のアクションは、**直接実行されているようで実はされていません**。  
その前後をがっつり取り囲むのが、**Interceptor（インターセプター）**。そして、Struts2がデフォルトで適用するInterceptorのセットこそが、今回の主役 **`defaultStack`** です。

---

## 🧱 Interceptorとは何か？（復習）

- **Struts2における“フィルター”のような存在**
- リクエスト処理の「前後」で共通処理を差し込める（Before／After）
- 実際には、**`ActionInvocation.invoke()`** を通してアクション実行が「チェーン状に」制御される

---

## 📦 defaultStackとは？

`defaultStack` とは、Struts2がデフォルトでアクションに適用する**Interceptorの集合体（プリセット）**です。

### 🔗 定義場所

`struts-default.xml` に定義されており、Struts2が提供する基盤Interceptorの一覧がここにまとめられています。

```xml
<interceptor-stack name="defaultStack">
    <interceptor-ref name="exception"/>
    <interceptor-ref name="alias"/>
    <interceptor-ref name="servlet-config"/>
    <interceptor-ref name="i18n"/>
    <interceptor-ref name="prepare"/>
    <interceptor-ref name="chain"/>
    <interceptor-ref name="debugging"/>
    <interceptor-ref name="profiling"/>
    <interceptor-ref name="scoped-model-driven"/>
    <interceptor-ref name="model-driven"/>
    <interceptor-ref name="fileUpload"/>
    <interceptor-ref name="checkbox"/>
    <interceptor-ref name="multiselect"/>
    <interceptor-ref name="static-params"/>
    <interceptor-ref name="action-mapping-params"/>
    <interceptor-ref name="params"/>
    <interceptor-ref name="conversionError"/>
    <interceptor-ref name="validation"/>
    <interceptor-ref name="workflow"/>
</interceptor-stack>
```
---

### 🔍 代表的なInterceptorたち（defaultStackの中身）

✅ `params`
- フォームの入力値（リクエストパラメータ）をアクションプロパティにバインド

- OGNLによるプロパティ設定がここで行われる

✅ `conversionError`
- 文字列→数値など、型変換時のエラーをキャッチしてエラーメッセージを生成

✅ `validation / workflow`
- `validation.xml` や `@Validations` に基づく入力チェックを実行

- エラーがある場合はアクション本体を呼び出さず、入力画面に戻す

✅ `fileUpload`
- アップロードされたファイルの一時保存、サイズ制限、MIME検査を実行

✅ `model-driven`
- `ModelDriven` インターフェースの `getModel()` を通じて入力モデルをバインド
---

### 🧪 defaultStack の実行順序とアクション呼び出しの流れ

Struts2の実行フローは、***Interceptorチェーン（InterceptorStack）を順に通過しながら進行***します。

```plaintext
(1) exception
↓
(2) alias
↓
(3) servlet-config
↓
...
↓
(17) validation
↓
(18) workflow → エラーなら終了、OKなら…
↓
★ Actionクラスの execute() 実行
```

この流れを知らないと、

- なぜアクションに入る前にエラーが出るのか？

- パラメータが突然消えるのはなぜか？
など、ブラックボックス感を持ったまま開発することになります。

---

### 💡 開発に役立つ defaultStack の活用術

### 🧭 1. 必要なInterceptorだけ使いたい場合

```xml
<action name="upload" class="...">
  <interceptor-ref name="fileUpload"/>
  <interceptor-ref name="params"/>
  <interceptor-ref name="workflow"/>
</action>
```

`defaultStack` を使わず、自前で組み立てれば、余分な機能を省けます。

---

### 🔧 2. 独自Interceptorの追加
たとえば、ログ出力や権限チェックなどを行う独自Interceptorを追加できます。

```xml
<interceptor name="authCheck" class="com.example.interceptor.AuthCheckInterceptor"/>

<action name="secureAction" class="...">
  <interceptor-ref name="authCheck"/>
  <interceptor-ref name="defaultStack"/>
</action>
```

※ 独自Interceptorは次回 Vol.11.4 で詳しく取り上げます。

---

### 🚨 よくある落とし穴


| 症状                         | 原因                                            |
| -------------------------- | --------------------------------------------- |
| `execute()` に入る前に画面遷移してしまう | `workflow` による validation エラーでスキップされている       |
| パラメータがバインドされない             | `params` がInterceptorStackに含まれていない or OGNLエラー |
| ファイルアップロードが動作しない           | `fileUpload` が入っていない／multipart/form-data 未指定  |


---

### ✅ まとめ

| 観点               | 内容                                 |
| ---------------- | ---------------------------------- |
| `defaultStack`とは | Struts2がアクション実行前後に適用するInterceptor群 |
| Interceptorの役割   | 共通処理（入力、検証、変換など）をアクションの外側で担う       |
| defaultStackの中身  | 18個前後のInterceptorが順に呼ばれる（順番に意味あり）  |
| カスタマイズ可能         | 自作Interceptor追加／構成の再定義もOK          |


---

### 🧩 次回予告：Vol.11.4 独自Interceptorの作り方と使い所
>「権限チェック」「操作ログ出力」「初期化処理」など、共通処理はInterceptorにまとめよう！
次回は 自作Interceptorの実装／テスト／組み込み手順を詳しく解説します。

>🎓 Interceptorを理解すれば、Struts2の本質が見えてくる。
アクションの“前後”を制する者は、UXと保守性を制す。

---

### 🧭 関連記事（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.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.7](https://qiita.com/juehara-crypto/items/ed8f0977c23ee8c8b959)     | validate() / input 戦略とUX設計                            | 開発スタイルの違い    
| [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連携）                             | 外部公開           |

---