アクションで生成した動的な値を、chainしたアクションで参照する方法

アクションクラスがchainで呼び出した次のアクションクラスへ値を渡すには、通常は前述したようなリクエストコンテキストやセッションコンテキストを利用します。しかし、Struts 2では、単純に次のアクションクラスへ値を渡すだけであれば、コンテキストやMapを利用する必要はありません。Struts 2では、アクションクラスの属性値はchainで呼び出した、次のアクションクラスの属性にコピーされるようになっています。コピーは同じ名前の属性に対して各アクションクラスのアクセッサメソッドを通して実施されます。実際のコードを例に説明します。

アクションクラスTopにゲストログインが実行された場合にtrueになる属性isGuestModeを追加し、この値をHelloUserアクションに渡すように、各アクションクラスを変更します。これを実装するのは非常に簡単で、両アクションクラスに属性isGuestModeとそのアクセッサメソッドを用意するだけです。ただ、isGuestModeに値をセットするために、guestLoginメソッドにてその処理を行うようにします。この変更をおこなったTopアクションクラスは以下のようになります。

リスト16: isGuestModeを追加したTop.java

package example;

import java.util.Map;

import org.apache.struts2.interceptor.SessionAware;

public class Top implements SessionAware {

    private String username;
    private String password;
    private String attention;
    private Map sessionMap;
    private boolean isGuestMode = false;

    public boolean getIsGestMode() {
        return isGuestMode;
    }

    public void setSession(Map sessionMap) {
        this.sessionMap = sessionMap;
    }

    public String getPassword() { return password; }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUsername() { return username; }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getAttention() { return attention; }

    public void setAttention(String attention) {
        this.attention = attention;
    }

    public String execute() throws Exception {
        setAttention("Please login!");
        return "success";
    }

    public String login() throws Exception {

        if ( username == null && password == null ) {
            return "input";
        }

        if ( ! username.equals(password)) {
            sessionMap.put("USERNAME", username);
            return "success";
        }

        return "input";
    }

    public String guestLogin() throws Exception {
        isGuestMode = true;
        return "success";
    }
}

Top_gestLoginアクションの次の処理をHelloUserアクションに変更するために、struts.xmlの定義を下記のようにchainに変更します。

リスト17: 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>
    <package name="example" namespace="/example" extends="struts-default">

        <action name="Top" class="example.Top">
            <result name="success" >/example/Top.jsp</result>
        </action>

        <action name="HelloUser" class="example.HelloUser">
            <result>/example/HelloUser.jsp</result>
        </action>

        <action name="Top_login"  method="login" class="example.Top" >
            <result name="input"   >/example/Top.jsp</result>
            <result name="success" type="chain" >HelloUser</result>
        </action>

        <action name="Top_guestLogin"  method="guestLogin" class="example.Top" >
            <result name="success" type="chain" >HelloUser</result>
        </action>

    </package>

</struts>

そして、HelloUserアクションのクラスHelloUser.javaに下記のようにisGuestMode属性とアクセッサメソッドを追加します。

リスト18: HelloUser.java

package example;

public class HelloUser  {

    private boolean isGuestMode;

    public boolean getIsGuestMode() { return isGuestMode; }

    public void setIsGestMode(boolean b){
        isGuestMode = b;
    }

    public String execute() throws Exception {
        return "success" ;
    }
}

あとは、guestLoginアクションが実行されるようにWebブラウザの[ゲストログイン]ボタンをクリックすれば、isGeustModeの値trueがHelloUserアクションクラスに伝播されます。

この機能によって、リクエストコンテキストやそれ相当のMapを利用せずに、簡単に次のアクションに値を渡す事ができ、非常に便利です。