Struts-2-struts-interceptors

提供:Dev Guides
移動先:案内検索

Struts 2-インターセプター

インターセプターは、概念的にはサーブレットフィルターまたはJDKプロキシクラスと同じです。 インターセプターにより、アクションおよびフレームワークとは別にクロスカット機能を実装できます。 あなたはインターセプターを使用して以下を達成することができます-

  • アクションが呼び出される前に前処理ロジックを提供します。

  • アクションが呼び出された後の後処理ロジックを提供します。

  • 代替処理を実行できるように例外をキャッチします。

    *Struts2* フレームワークで提供される機能の多くは、インターセプターを使用して実装されています。
  • 例*には、例外処理、ファイルのアップロード、ライフサイクルコールバックなどが含まれます。 実際、Struts2はインターセプターの機能の多くを強調しているため、アクションごとに7つまたは8つのインターセプターが割り当てられることはほとんどありません。

Struts2フレームワークインターセプター

Struts 2フレームワークは、事前構成されてすぐに使用できるすぐに使用可能なインターセプターの優れたリストを提供します。 重要なインターセプターのいくつかは以下にリストされています-

Sr.No Interceptor & Description
1

alias

パラメータがリクエスト間で異なる名前エイリアスを持つことを許可します。

2

checkbox

チェックされていないチェックボックスにfalseのパラメーター値を追加することにより、チェックボックスの管理を支援します。

3

conversionError

エラー情報を、文字列からパラメータータイプへの変換からアクションのフィールドエラーに配置します。

4

createSession

HTTPセッションがまだ存在しない場合、自動的に作成します。

5

debugging

開発者にいくつかの異なるデバッグ画面を提供します。

6

execAndWait

アクションがバックグラウンドで実行されている間に、ユーザーを中間の待機ページに送ります。

7

exception

アクションからスローされた例外を結果にマップし、リダイレクトによる自動例外処理を可能にします。

8

fileUpload

簡単なファイルのアップロードを容易にします。

9

i18n

ユーザーのセッション中に選択したロケールを追跡します。

10

logger

実行中のアクションの名前を出力することにより、簡単なロギングを提供します。

11

params

アクションの要求パラメーターを設定します。

12

prepare

これは通常、セットアップデータベース接続などの前処理作業を行うために使用されます。

13

profile

アクションの単純なプロファイリング情報を記録できます。

14

scope

セッションまたはアプリケーションスコープでアクションの状態を保存および取得します。

15

ServletConfig

アクションにさまざまなサーブレットベースの情報へのアクセスを提供します。

16

timer

アクションの実行にかかる時間の形式で、単純なプロファイリング情報を提供します。

17

token

有効なトークンのアクションをチェックして、フォーム送信の重複を防ぎます。

18

validation

アクションの検証サポートを提供します

上記のインターセプターの詳細については、Struts 2のドキュメントをご覧ください。 ただし、Strutsアプリケーションで一般的なインターセプターの使用方法を説明します。

インターセプターの使用方法

既存のインターセプターを「Hello World」プログラムに使用する方法を見てみましょう。 アクションメソッドの実行にかかった時間を測定することを目的とする timer インターセプターを使用します。 同時に、リクエストパラメータをアクションに送信することが目的の params インターセプタを使用しています。 このインターセプターを使用せずに例を試すと、パラメーターがアクションに到達できないため、 name プロパティが設定されていないことがわかります。

例*の章で作成したHelloWorldAction.java、web.xml、HelloWorld.jspおよびindex.jspファイルを保持しますが、 *struts.xml ファイルを変更してインターセプターを追加します。

<?xml version = "1.0" Encoding = "UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
   <constant name = "struts.devMode" value = "true"/>

   <package name = "helloworld" extends = "struts-default">
      <action name = "hello"
         class = "com.finddevguides.struts2.HelloWorldAction"
         method = "execute">
         <interceptor-ref name = "params"/>
         <interceptor-ref name = "timer"/>
         <result name = "success">/HelloWorld.jsp</result>
      </action>
   </package>
</struts>

プロジェクト名を右クリックし、[エクスポート]> [WARファイル]をクリックして、WARファイルを作成します。 次に、このWARをTomcatのwebappsディレクトリにデプロイします。 最後に、Tomcatサーバーを起動して、URL http://localhost:8080/HelloWorldStruts2/index.jsp にアクセスしてみます。 これにより、次の画面が生成されます-

Hello World Struts 4

指定されたテキストボックスに任意の単語を入力し、[Say Hello]ボタンをクリックして、定義されたアクションを実行します。 生成されたログを確認する場合、次のテキストが表示されます-

INFO: Server startup in 3539 ms
27/08/2011 8:40:53 PM
com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: Executed action [//hello!execute] took 109 ms.

ここでは、 timer インターセプターがアクションの実行に合計109ミリ秒かかったことを示すため、最終行が生成されています。

カスタムインターセプターを作成する

アプリケーションでカスタムインターセプターを使用することは、横断的なアプリケーション機能を提供するエレガントな方法です。 カスタムインターセプターの作成は簡単です。拡張する必要があるインターフェイスは、次の Interceptor インターフェイスです-

public interface Interceptor extends Serializable {
   void destroy();
   void init();
   String intercept(ActionInvocation invocation)
   throws Exception;
}

名前が示すように、init()メソッドはインターセプターを初期化する方法を提供し、destroy()メソッドはインターセプターのクリーンアップ機能を提供します。 アクションとは異なり、インターセプターはリクエスト間で再利用されるため、スレッドセーフ、特にintercept()メソッドが必要です。

*ActionInvocation* オブジェクトは、ランタイム環境へのアクセスを提供します。 アクション自体とメソッドにアクセスしてアクションを呼び出し、アクションがすでに呼び出されているかどうかを判断できます。

初期化またはクリーンアップコードが必要ない場合は、 AbstractInterceptor クラスを拡張できます。 これにより、init()およびdestroy()メソッドのデフォルトのnooperation実装が提供されます。

インターセプタークラスを作成する

*Java Resources> src* フォルダに次のMyInterceptor.javaを作成しましょう-
package com.finddevguides.struts2;

import java.util.*;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class MyInterceptor extends AbstractInterceptor {

   public String intercept(ActionInvocation invocation)throws Exception {

     /*let us do some pre-processing*/
      String output = "Pre-Processing";
      System.out.println(output);

     /*let us call action or next interceptor*/
      String result = invocation.invoke();

     /*let us do some post-processing*/
      output = "Post-Processing";
      System.out.println(output);

      return result;
   }
}

お気づきのとおり、実際のアクションは** invocation.invoke()* *callによってインターセプターを使用して実行されます。 したがって、要件に基づいて前処理と後処理を行うことができます。

フレームワーク自体は、ActionInvocationオブジェクトのinvoke()を最初に呼び出すことでプロセスを開始します。* invoke()*が呼び出されるたびに、ActionInvocationはその状態を調べ、次に来るインターセプターを実行します。 設定されたすべてのインターセプターが呼び出されると、invoke()メソッドによりアクション自体が実行されます。

次の図は、要求フローを通じて同じ概念を示しています-

ActionInvocation

アクションクラスの作成

*Java Resources> src* の下に *com.finddevguides.struts2* というパッケージ名のJavaファイルHelloWorldAction.javaを作成します。内容は以下のとおりです。
package com.finddevguides.struts2;

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorldAction extends ActionSupport {
   private String name;

   public String execute() throws Exception {
      System.out.println("Inside action....");
      return "success";
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }
}

これは、前の例で見たのと同じクラスです。 「name」プロパティ用の標準のゲッターおよびセッターメソッドと、文字列「success」を返すexecuteメソッドがあります。

ビューを作成する

eclipseプロジェクトのWebContentフォルダーに以下のjspファイル HelloWorld.jsp を作成しましょう。

<%@ page contentType = "text/html; charset = UTF-8" %>
<%@ taglib prefix = "s" uri = "/struts-tags" %>

<html>
   <head>
      <title>Hello World</title>
   </head>

   <body>
      Hello World, <s:property value = "name"/>
   </body>
</html>

メインページを作成

また、WebContentフォルダーに index.jsp を作成する必要があります。 このファイルは、ユーザーがクリックしてStruts 2フレームワークにHelloWorldActionクラスの定義済みメソッドを呼び出し、HelloWorld.jspビューをレンダリングするように指示できる初期アクションURLとして機能します。

<%@ page language = "java" contentType = "text/html; charset = ISO-8859-1"
   pageEncoding = "ISO-8859-1"%>
<%@ taglib prefix = "s" uri = "/struts-tags"%>
   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
   <head>
      <title>Hello World</title>
   </head>

   <body>
      <h1>Hello World From Struts2</h1>
      <form action = "hello">
         <label for = "name">Please enter your name</label><br/>
         <input type = "text" name = "name"/>
         <input type = "submit" value = "Say Hello"/>
      </form>
   </body>
</html>

上記のビューファイルで定義された hello アクションは、struts.xmlファイルを使用してHelloWorldActionクラスとその実行メソッドにマッピングされます。

構成ファイル

ここで、インターセプターを登録してから、前の例でデフォルトのインターセプターを呼び出したように呼び出す必要があります。 新しく定義されたインターセプターを登録するには、<interceptors> …​ </interceptors>タグを<package>タグのins * struts.xml *ファイルの直下に配置します。 前の例で行ったように、デフォルトのインターセプターではこのステップをスキップできます。 しかし、ここで次のように登録して使用してみましょう-

<?xml version = "1.0" Encoding = "UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
   <constant name = "struts.devMode" value = "true"/>
   <package name = "helloworld" extends = "struts-default">

      <interceptors>
         <interceptor name = "myinterceptor"
            class = "com.finddevguides.struts2.MyInterceptor"/>
      </interceptors>

      <action name = "hello"
         class = "com.finddevguides.struts2.HelloWorldAction"
         method = "execute">
         <interceptor-ref name = "params"/>
         <interceptor-ref name = "myinterceptor"/>
         <result name = "success">/HelloWorld.jsp</result>
      </action>

   </package>
</struts>
*<package>* タグ内で複数のインターセプターを登録でき、同時に *<action>* タグ内で複数のインターセプターを呼び出すことができることに注意してください。 同じインターセプターを異なるアクションで呼び出すことができます。

web.xmlファイルは、次のようにWebContentの下のWEB-INFフォルダーの下に作成する必要があります-

<?xml version = "1.0" Encoding = "UTF-8"?>
<web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xmlns = "http://java.sun.com/xml/ns/javaee"
   xmlns:web = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee
   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id = "WebApp_ID" version = "3.0">

   <display-name>Struts 2</display-name>

   <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>

   <filter>
      <filter-name>struts2</filter-name>
      <filter-class>
         org.apache.struts2.dispatcher.FilterDispatcher
      </filter-class>
   </filter>

   <filter-mapping>
      <filter-name>struts2</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>
</web-app>

プロジェクト名を右クリックし、[エクスポート]> [WARファイル]をクリックして、WARファイルを作成します。 次に、このWARをTomcatのwebappsディレクトリにデプロイします。 最後に、Tomcatサーバーを起動して、URL http://localhost:8080/HelloWorldStruts2/index.jsp にアクセスしてみます。 これにより、次の画面が生成されます-

Hello World Struts 4

指定されたテキストボックスに任意の単語を入力し、[Say Hello]ボタンをクリックして、定義されたアクションを実行します。 今、あなたが生成されたログを確認する場合は、下部に次のテキストがあります-

Pre-Processing
Inside action....
Post-Processing

複数のインターセプターのスタック

ご想像のとおり、アクションごとに複数のインターセプターを構成する必要があると、すぐに管理できなくなります。 このため、インターセプターはインターセプタースタックで管理されます。 以下は、strutsdefault.xmlファイルから直接の例です-

<interceptor-stack name = "basicStack">
   <interceptor-ref name = "exception"/>
   <interceptor-ref name = "servlet-config"/>
   <interceptor-ref name = "prepare"/>
   <interceptor-ref name = "checkbox"/>
   <interceptor-ref name = "params"/>
   <interceptor-ref name = "conversionError"/>
</interceptor-stack>

上記のステークは basicStack と呼ばれ、以下に示すように構成で使用できます。 この構成ノードは、<package …​/>ノードの下に配置されます。 各<interceptor-ref …​/>タグは、インターセプターまたは現在のインターセプタースタックの前に構成されたインターセプタースタックを参照します。 したがって、初期インターセプターとインターセプタースタックを構成するときは、名前がすべてのインターセプターとインターセプタースタック構成で一意であることを確認することが非常に重要です。

インターセプターをアクションに適用する方法はすでに見てきましたが、インターセプタースタックの適用も同じです。 実際には、まったく同じタグを使用します-

<action name = "hello" class = "com.finddevguides.struts2.MyAction">
   <interceptor-ref name = "basicStack"/>
   <result>view.jsp</result>
</action

上記の「basicStack」の登録は、helloアクションで6つのインターセプターすべての完全なステークを登録します。 これは、インターセプターが構成された順序で実行されることに注意してください。 たとえば、上記の場合、例外が最初に実行され、2番目がservlet-configなどになります。