0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

📘 Vol.6:BaseActionクラスの詳細解説【Struts2の要】

Last updated at Posted at 2025-05-19

本章では、掲示板アプリケーションの多くのアクションが継承して利用する、共通処理クラス BaseActionクラス について解説します。


1. BaseActionクラスとは?

BaseAction クラスは、Struts2で使用される共通アクションクラスです。
このクラスを継承することで、以下のような共通機能を全アクションクラスで使えるようになります:

  • セッション情報の取得
  • リクエスト情報の取得
  • ユーザーIDやスレッドIDなどの保持
  • リクエストパラメータの共通取得
  • 処理メソッドの定義(mainProc()

2. 実装しているインタフェース(Struts2独自)

Struts2 では、以下のインタフェースを実装することで、セッションやリクエスト情報が自動的に"注入" されます。

実装インタフェース フレームワーク/Java 注入されるオブジェクト 説明
SessionAware Java Map session セッション情報を取得するためのIF
ServletRequestAware Struts2 HttpServletRequest request HTTPリクエストを取得するためのIF
ServletResponseAware Struts2 HttpServletResponse response HTTPレスポンスを扱うためのIF

💬 補足:「注入される」とは?

Javaのクラスの中で new などを使って自分でオブジェクトを作るのではなく、
フレームワーク側が必要な情報を自動で渡してくれる 仕組みのことを「注入(インジェクション)」と言います。

例)sessionrequest 変数は自動的にセットされて利用可能になります!


3. BaseActionのコード(Java)

package com.company.bulletinboard.interceptor;

import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.interceptor.SessionAware;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;

public abstract class BaseAction implements SessionAware, ServletRequestAware, ServletResponseAware {

    protected Map<String, Object> session;
    protected HttpServletRequest request;
    protected HttpServletResponse response;

    protected String user_id;
    protected String thread_id;
    protected String board_id;
    protected String action;

    @Override
    public void setSession(Map<String, Object> session) {
        this.session = session;
        // セッションからログイン中のuser_idを取得して保持
        this.user_id = (String) session.get("user_id");
    }

    @Override
    public void setServletRequest(HttpServletRequest request) {
        this.request = request;
        // URLパラメータやリクエストスコープの情報を取得
        this.thread_id = request.getParameter("thread_id");
        this.board_id = request.getParameter("board_id");
        this.action = request.getParameter("action");
    }

    @Override
    public void setServletResponse(HttpServletResponse response) {
        this.response = response;
    }

    // 各アクションがオーバーライドして処理内容を記述
    public abstract String mainProc();
}

4. 継承クラスでの使われ方

この BaseAction を他のアクションクラスが継承し、共通の mainProc() メソッドをオーバーライドして実装します。

✅ 例:スレッド作成用の CreateThreadAction クラス

public class CreateThreadAction extends BaseAction {

    @Override
    public String mainProc() {
        // BaseAction から引き継いだ board_id や user_id を使用可能
        System.out.println("掲示板ID: " + board_id);
        System.out.println("ログインユーザー: " + user_id);

        // スレッド作成処理をここで実装
        // ...

        return "success";
    }
}

5. リクエストで取得した値を使える理由

BaseActionServletRequestAware を実装しているため、
Struts2 のライフサイクル中にリクエストが自動的に注入され、
それによりパラメータ(例:board_id, thread_id など)を どの継承先でも使える状態 にしています。

これにより、同じようなコードを何度も書かずに済む=DRY原則 を実現できます!


6. 共通ログ出力処理の実装

BaseAction には、各アクションの処理開始・終了時にログを出力する共通ロジックを組み込んでいます。

これにより、どのアクションでもログ出力コードを毎回書く必要がなくなり、保守性と可読性が向上します。

✅ 例:BaseAction におけるログ出力処理の実装例

public abstract class BaseAction implements SessionAware, ServletRequestAware, ServletResponseAware {

    protected HttpServletRequest request;
    protected HttpServletResponse response;
    protected Map<String, Object> session;
    protected String user_id;
    protected String board_id;
    protected String thread_id;

    @Override
    public String execute() throws Exception {
        System.out.println("=== " + this.getClass().getSimpleName() + " 開始 ===");
        String result = mainProc();
        System.out.println("=== " + this.getClass().getSimpleName() + " 終了: result = " + result + " ===");
        return result;
    }

    public abstract String mainProc();
}

このように execute() の中でログ出力することで、全アクションの実行ログが自動的に記録されます。

このログ出力の共通化によって、次のようなメリットがあります:

  • デバッグ時の トレース性が向上

  • 処理の流れを 簡単に追跡できる

  • エラー原因の早期発見 がしやすくなる

こうした 「共通ログ出力」も BaseAction を導入する大きな理由の一つ です。

なお、サンプルコードでは分かりやすさを優先して System.out.println を使用していますが、
本番環境ではログフレームワーク(例:org.slf4j.LoggerLog4j)を利用することを強くおすすめします。

ログフレームワークを使うことで以下のようなメリットがあります:

  • ログレベル(INFO, DEBUG, ERRORなど)の柔軟な管理
  • ログの出力先(ファイル、コンソール、リモートサーバなど)の切り替えが簡単
  • フォーマットやローテーションなどの高度な設定が可能

例えば、Logger を使った例は以下の通りです:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BaseAction implements Action {
    private static final Logger logger = LoggerFactory.getLogger(BaseAction.class);

    @Override
    public String execute() throws Exception {
        logger.info("=== {} 開始 ===", this.getClass().getSimpleName());
        String result;
        try {
            result = mainProc();
        } catch (Exception e) {
            logger.error("エラー発生:", e);
            result = "error";
        }
        logger.info("=== {} 終了: result = {} ===", this.getClass().getSimpleName(), result);
        return result;
    }
}

このようにすれば、運用に適したログ管理ができ、開発・保守が一層効率的になります。


7. 共通エラーハンドリングの実装

BaseAction に try-catch を組み込み、全アクションでの共通的なエラー処理を実装することができます。

@Override
public String execute() throws Exception {
    System.out.println("=== " + this.getClass().getSimpleName() + " 開始 ===");
    String result;
    try {
        result = mainProc();
    } catch (Exception e) {
        System.err.println("エラー発生: " + e.getMessage());
        e.printStackTrace();
        result = "error"; // 共通エラー画面などに遷移
    }
    System.out.println("=== " + this.getClass().getSimpleName() + " 終了: result = " + result + " ===");
    return result;
}

このようにすることで:

  • 各アクションクラスで try-catch を書く必要がなくなる

  • 共通のエラーページやログ記録処理に一元対応できる

  • アプリ全体の安定性と信頼性が向上

といったメリットがあります。


8.Struts2 の Interceptor との併用による拡張性

Struts2 の Interceptor(インターセプター)機能と組み合わせることで、以下のような 関心の分離(Separation of Concerns) が可能になります:

処理 実装箇所
認証チェック Interceptor
ログ出力 BaseAction(または Interceptor)
パラメータ処理 BaseAction
アプリ固有の処理 各 Action クラスの mainProc()

✅ Interceptor との役割分担例

  • Interceptor:認証チェック、トランザクション制御、入力検証 など

  • BaseAction:パラメータ取得・共通ログ・エラー処理 など

  • 各 Action クラス:ビジネスロジック(スレッド作成、投稿など)

このように設計することで、責務が明確化されて再利用性が高まり、保守性にも優れる構成になります。


9. まとめ

  • BaseAction は「パラメータ処理」「共通ログ出力」「共通エラーハンドリング」などを担う基盤クラス

  • Struts2の機能で**セッション・リクエストなどが自動で「注入」**される

  • 継承先では mainProc() をオーバーライドして具体的な処理を記述

  • 画面遷移ごとに request.getParameter() を書かなくても済むのがポイント

  • Interceptor を併用することで、よりクリーンで拡張可能なアーキテクチャが実現できる


📝 📘 Vol.6.1 BaseAction の活用例【共通基底クラスでセッション管理を簡素化】では、この BaseAction の活用例を具体的に紹介していきます!
CreateThreadActionPostAction の中で、どのように活かされているかを詳しく見ていきましょう!


🧭 Vol.1〜7 関連リンク

タイトル 主な内容
Vol.1 プログラミングとの再会 – 「画面ありき」で変わった学び方 プログラミング再入門と、画面駆動の学習法というユニークなアプローチの紹介。最初に「画面」から考えることでモチベーションを継続。
Vol.2 画面駆動設計に基づく設計書の具体例:画面フローからUI設計・処理定義まで 実際に描いた画面遷移図・UI設計・処理定義書を公開し、画面中心の設計手法を解説。
Vol.3 詳細設計編:ER図で見るデータ構造と実装の土台 実装前提で設計された ER図(Entity Relationship 図) をもとに、データ構造と整合性を設計。
Vol.4 Struts2とMavenの基礎と設定ファイルの役割 Struts2の構成とMavenでの管理、web.xmlpom.xml の役割を丁寧に解説。
Vol.5 環境構築編:掲示板アプリケーションの実行準備 TomcatとEclipseでの動作環境構築。
Vol.6.1 BaseAction の活用例【共通基底クラスでセッション管理を簡素化】 BaseAction を継承する具体的なアクション例を紹介し、セッションやログ処理の統合例を実践。
Vol.7 Struts2 における MVC モデルの全体像 Model-View-Controller の各要素が Struts2 でどう分担されるかを体系的に解説。
Vol.7.1 Struts2 における Model(モデル)について JavaBeansベースのModelクラス(User, Thread, Post など)設計とその役割を明確化。
Vol.7.2 Struts2 における Controller(コントローラ)の責務 Actionクラスを軸に、入力処理・分岐処理・画面遷移の中核を担うControllerの実装指針を提示。
Vol.7.3 Struts2 における struts.xml の書き方と役割 URLマッピング、結果遷移、アクション定義の方法を丁寧に記述。初心者の詰まりやすいポイントを回避。
Vol.7.4 struts.xmlの高度な設定と実践活用(Struts2) namespaceの活用や画面単位での分離設計、開発時の保守性向上テクニックを紹介。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?