SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

作りながら学ぶJavaアプリケーションフレームワーク

Struts 2入門(4)~インターセプターという仕組み~

作りながら学ぶJavaアプリケーションフレームワーク

独自のインターセプター

 では、かんたんなインターセプターを作ってみましょう。自作したインターセプターで動きを確かめてみます。

Interceptor本体

 インターセプター本体は、com.opensymphony.xwork2.interceptor.Interceptorインターフェイスを実装する必要があります。Interceptorインターフェイスには、下記のように3つのメソッドが定義してあり、すべて実装しなければなりません。

 ただし、com.opensymphony.xwork2.interceptor.AbstractInterceptorというクラスで、Interceptorインターフェイスのinitメソッドとdestroyメソッドが実装されています。内容のない空のメソッドが定義されているだけですが、これを継承してインターセプターを作ると、不要な実装を記述する手間が省けます。

[リスト2]Interceptorインターフェイスの定義
public interface Interceptor extends Serializable {
    void destroy();
    void init();
    String intercept(ActionInvocation invocation) throws Exception;
}

void init()

 Servletコンテナ(Tomcat)を起動すると呼ばれます。

void destroy()

 Servletコンテナの終了時に呼ばれます。

String intercept(ActionInvocation invocation)

 このメソッドに、インターセプターの処理を記述します。パラメータのActionInvocationオブジェクトを使って、リクエストパラメータやセッションにアクセスします。

 ActionInvocationオブジェクトは、Actionクラスを実行したときのステータス情報を格納しており、Actionとインターセプターのインスタンスも保持しています。

 例えば、 次のようなコードでリクエストパラメータやセッションや取得することができます。

[リスト3]interceptメソッド内に記述するコード
// セッションの取得
// Struts 2では、Mapオブジェクトとしてセッションが取得できる
Map<String, String> session = ActionContext.getContext().getSession();

// HttpServletRequest、HttpSessionの取得
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = ServletActionContext.getRequest().getSession();

 com.opensymphony.xwork2.ActionContextとは、セッション、リクエストパラメータ、ロケール情報などを保持するクラスで、org.apache.struts2.ServletActionContextは、ActionContextの派生クラスです。

 詳細は、オンラインのドキュメントを参照してください。これらのオブジェクトを利用して行えるのは、セッションやリクエストパラメータの取得、Actionオブジェクトの名前の参照、結果コードの参照や変更などです。

Interceptorのサンプルコード

 以下は、AbstractInterceptorを継承したインターセプターの例です。このクラスを、連載で使用しているサンプルプロジェクトに組み込んでみましょう。

[リスト4]SimpleInterceptor.java
package part4;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class SimpleInterceptor extends AbstractInterceptor {

    private static final long serialVersionUID = 1L;

    // インターセプターの処理(コンソールに文字列を出力する)
    public String intercept(ActionInvocation invocation) throws Exception {

        System.out.println("intercept処理");

        // 次のインターセプター処理
        String result_code = invocation.invoke();

        // Result後のインターセプター処理
        System.out.println("intercept処理2");

        return result_code;
    }
}

 このインターセプターは、コンソールに文字列を出力するだけのものです。interceptメソッドの最後で、次のインターセプター処理を継続するために、invocation.invoke()メソッドを呼んでいます。そのメソッドを呼び出さず、Actionクラスと同様に、直接、"success"などの結果のコードを返すことができます。その場合は、直後のActionクラスの実行もスキップされることになります。

 なお、invocation.invoke()から戻ってきた後は、結果の処理も終わっています。この例では、結果の画面が表示されてから、二度目のSystem.out.printlnの出力処理を行っています。

 次に、設定ファイルのstruts.xmlを変更します。

[リスト5]struts.xml(追加)
<interceptors>

    <!-- interceptorの定義 -->
    <interceptor name="simple" class="part4.SimpleInterceptor"/>

    <!-- interceptorをグルーピング -->
    <interceptor-stack name="simpleInterceptorStack" >
        <!-- 呼び出したい順にinterceptorを記述する -->
        <interceptor-ref name="simple" />
        <interceptor-ref name="defaultStack"/>
    </interceptor-stack>

</interceptors>

<action name="Hello" class="part1.Hello">

    <!-- interceptorの指定 -->
    <interceptor-ref name="simpleInterceptorStack"/>

    <result name="success">/index.jsp</result>
</action>

 <interceptors>~</interceptors>タグ間で、インターセプターの定義をします。そして、<interceptor>タグのname属性で名称、class属性で、インターセプター本体のクラスを指定します。

 前述したように、<interceptor-stack>タグはインターセプターのグルーピング指定です。複数のインターセプターをまとめて定義することができます。

 Actionクラスごとに指定するインターセプターは、デフォルトのインターセプターとの差分だけという指定ができないので、基本的には常にデフォルトのインターセプター(struts-default.xmlで指定されたdefaultStack)も指定する必要があります。通常、複数のインターセプターを指定することになりますので、グルーピングの設定をしておくと、Actionに適用するインターセプターを1つのグループ名で指定できるようになります。

 <action>タグ内の<interceptor-ref>タグで、そのActionに適用するインターセプターを指定します。この指定がない場合は、defaultStackが指定されたことになります。

 なお、すべてのActionに適用する場合は、defaultStack自体のグルーピングをstruts.xmlにて上書き設定するか、<default-interceptor-ref>タグを使って、デフォルトのインターセプターを再定義するとよいでしょう(<default-interceptor-ref>タグを使う例は、後述します)。

 さっそく、Eclipseからこのアプリケーションを実行して、「こんにちは」のリンクをクリックしてください。次のように、Eclipseのコンソールに、intercept処理とintercept処理2という文字列が、出力されるはずです。

intercept処理
....
intercept処理2

Actionが実行された後のインターセプター

 Actionが実行された後(Resultオブジェクトが処理をする前)にも、インターセプターのメソッドを呼び出すことができます。これは、Action結果のコードを判断して、何らかの処理を行いたい場合や、強制的に結果コードを変更したいときに利用できます。

 Actionの後に実行するメソッドは、次のように、ActionInvocationクラスのaddPreResultListenerメソッドを用いて設定します。

[リスト6]変更したinterceptメソッド
public String intercept(ActionInvocation invocation) throws Exception {

    System.out.println("intercept処理");

    invocation.addPreResultListener(
        new PreResultListener() {
            public void beforeResult(ActionInvocation actioninvocation, String resultCode) {
                System.out.println("Result:"+resultCode);
           }
       }
    );

    // 次のインターセプター処理
    String result_code = invocation.invoke();

    // Result後のインターセプター処理
    System.out.println("intercept処理2");

    return result_code;
}

 com.opensymphony.xwork2.interceptor.PreResultListenerは、beforeResultメソッドのみを定義したインターフェイスです。beforeResultメソッドが、コールバックとして実行されることになりますので、ここに処理を記述します。

 beforeResultメソッドには、Actionの結果コードがパラメータで渡されます。上記のコード例は、その結果コードをコンソールに出力するものです。

次のページ
ログイン認証のインターセプター

この記事は参考になりましたか?

作りながら学ぶJavaアプリケーションフレームワーク連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 高江 賢(タカエ ケン)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/3264 2008/11/27 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー