HTML入力フォームの値をアクションクラスで参照する方法

Struts 2では、入力フォームの値は呼び出されたアクションクラスの属性として参照できます。すなわち、フォームのサブミット先のアクションに対応したアクションクラスに直接セットされ、その値をメソッド内で参照するという事です。先のJSPのusernameとpasswordという2つの入力フィールドを持つフォームに対応したアクションクラスには、usernameとpasswordという2つの属性を定義し、そのアクセッサメソッドを用意すればよいのです。

最初の例のアクションクラスTopにこの2つの属性を定義したクラスは以下のようになります。

リスト7: username、passwordの2つの属性を追加したTop.java

package example;

public class Top {

    private String username;
    private String password;

    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 execute() throws Exception {
        return "success";
    }

}

JSFと同様にWebブラウザのイベントに対応して呼び出されるクラスに、メソッド(処理)と属性(データ)をパッケージングでき、オブジェクト指向的にView(MVCモデル2のView)のクラスを設計する事ができるようになっています。ただし、このままでは前述したJSPが生成したフォームのサブミットを受け取れません。なぜなら、前述のJSPのフォームは2つの異なるアクションを呼び出すサブミットボタンがありましたが、これに対応するアクションがまだ実装されていないからです。この方法を次節で紹介しましょう。

1つのフォームに複数のボタンを配置する方法

1つのフォームに複数のボタンを配置し、それぞれ異なる処理を実行させるのは、一般的なWebアプリケーションであれば当然のようにある事です。ここでは、その実装方法を紹介します。JSP側の定義の方法は、すでに「JSPページの作成方法」の中で紹介していますので、以下ではこの2つのアクションとアクションクラスの記述方法を紹介します。

まずはアクションの定義から説明しましょう。アクションの定義は、最初の例で紹介した記述と同様に、<s:submit>タグにて指定したアクションを下記のようにstruts.xmlに追加定義します。

リスト8: 2つのアクションを追加した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="Top_login"  method="login" class="example.Top" >
            <result name="input"   >/example/Top.jsp</result>
        </action>

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

    </package>

</struts>

これで、Top、Top_login、Top_guestLoginの3つのアクションが定義された事になります。3つのアクションは全てexample.Topクラスが実装するように定義しています。今回追加したTop_loginとTop_guestLoginアクションが、Topアクションの定義と異なる点は、<action>要素にmethod属性を指定している点と、outcomeが"input"になっている点だけです。まず、method属性ですが、これはご想像通りclass属性に指定したクラスを呼び出す際のメソッドをデフォルトのexecuteではなく、指定のメソッドを呼び出す事を定義しています。これによって、Top_loginアクションはloginメソッドを、Top_guestLoginアクションはguestLoginメソッドをそれぞれ呼び出すようになります。このメソッドを実装したアクションクラスは下記のようになります。

リスト9: ボタンに対応したメソッドを追加したTop.java

package example;

public class Top {

    private String username;
    private String password;

    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 execute() throws Exception {
        return "success";
    }

    public String login() throws Exception {
        return "input";
    }

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

}

outcomeに文字列"input"を返すだけのloginと、guestLoginという2つのメソッドが追加されたのみですが、この状態でアプリケーションを実行すると、Top.jspを表示する前にはexecuteメソッドが、それぞれのボタンをクリックすると対応したメソッドが実行されるようになります。ここまでくると、本格的なWebアプリケーションの実装方法が少し見えてきたのではないでしょうか。