インターセプタのジャンル分け
実装されているインターセプタを大別すると次のように分けられます。
- Actionクラスの制御に関するもの
- サーブレット属性に関するもの
- パラメータ操作に関するもの
- 同梱されるStruts 2プラグイン(注1)によって提供されるもの。
- デバッグ用のインターセプタ
複数のジャンルにかかるものもひとまず一箇所にまとめています。
今回はActionクラスの制御に関するものを取り上げます。残りについては、次回紹介いたします。
Struts 2の機能を拡張するライブラリをプラグインと呼びます。プラグインについては次回以降紹介する予定です。
Actionクラスの制御に関するもの
ここではActionクラスの動きを制御するインターセプタを挙げていきます。インターセプタを適用することで動きが変わっていき、デフォルトのインターセプタ・スタックで適用されているものもあります。ここでは良く使われると思われるインターセプタについて解説していきます。
(1)Chaining Interceptor
元Actionのフィールドの初期値を引き継ぐリクエストのフォワードを行います。ActionのResultTypeにchainを指定する際に使われます。
//Actionクラスのグループをchainに指定
@Namespace(value="/chain")
// Actionメソッドの戻り値と遷移先画面を指定
@Results({
@Result(name="success" , location="success.jsp") ,
// type="chain"時、locationに指定したActionクラス/メソッドへ遷移
@Result(name="chainResult" , type="chain" , location="chainAction"),
})
public class ChainSampleAction extends ActionSupport {
private static Logger log = Logger.getLogger(ChainSampleAction.class);
// start.actionで起動
@Action(value="start")
public String execute() throws Exception {
return "success";
}
// chainStart.actionで起動
@Action(value="chainStart" )
public String chainStart() throws Exception {
// value2の値に文字列を追加
value2 += "+chain+";
log.debug(value1 + "/" + value2 + ".");
return "chainResult";
}
private String value1;
private String value2;
public String getValue1() {
return value1;
}
public void setValue1(String value1) {
this.value1 = value1;
}
public String getValue2() {
return value2;
}
public void setValue2(String value2) {
this.value2 = value2;
}
}
type="chain"を指定することで、locationで指定した別のActionクラスへ遷移します。この例ではchainActionと記述されていますので、chainAction.actionが呼ばれます。
このActionクラスのどの時点での値を引き継いでいるかを調べるため、画面から渡されたvalue2の値の後ろに +chain+ をつけることにしました。
次にchainで指定先として選ばれたActionクラスです。先ほど指定したchainActionが@Actionアノテーションで指定されていますので、このActionクラスが起動します。type="chain"によって呼び出されたActionクラスは、呼び出し元のActionクラスのフィールドの初期値を引き継ぎます。
@Namespace(value="/chain")
@Results({
@Result(name="success" , location="success.jsp"),
})
public class ChainAnotherSampleAction extends ActionSupport {
private static Logger log = Logger.getLogger(ChainAnotherSampleAction.class);
// chainAction.actionで起動
@Action(value="chainAction")
public String execute() throws Exception {
log.debug(value1 + "/" + value2 + ".");
return "success";
}
private String value1;
private String value2;
public String getValue1() {
return value1;
}
public void setValue1(String value1) {
this.value1 = value1;
}
public String getValue2() {
return value2;
}
public void setValue2(String value2) {
this.value2 = value2;
}
}
では実際にサンプルを動かして確認してみましょう。
ブラウザでhttp://127.0.0.1:8080/interceptors/chain/start.actionを表示します。

この画面のテキストボックスに値を入力し、「ActionChainを稼動する」ボタンを押すことでテキストボックスの内容がChainSampleActionクラスへ渡され、さらにChaining InterceptorによってChainAnotherSampleActionクラスへと自動的に遷移します。この動作をそれぞれのActionクラスにてログで出力していますので、そのログの結果は次のように表示されます。

画面からActionクラスのvalue1,value2が伝播されていることがわかります。そしてvalue2に+chain+がつけられていることもログで確認され、Chaining Interceptorで遷移したActionクラスでは、加工前のvalue2の値になっていることもわかります。
このログからわかることは、遷移したChainAnotherSampleActionではChainSampleActionの初期値がそのまま渡されていることになります。
結果画面も同様にvalue1,value2が渡されますので、次のように表示されます。

