昨日の続き。ActionForm を実際に使ってみよう。

作ったフォームクラスを利用するためには、
Struts の設定ファイルに登録する必要がある。

========== /WEB-INF/struts-config.xml ==========
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts-config PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
        "http://jakarta.apache.org/struts/dtds/struts-config_1_3.dtd">

<struts-config>

<form-beans>
    <form-bean name="loginForm" type="jp.loafer.test.forms.LoginForm" />
</form-beans>

<action-mappings>

    <action path="/index" forward="/WEB-INF/pages/login.jsp" />
   
    <action path="/login" name="loginForm"
            type="jp.loafer.test.actions.LoginAction">
        <forward name="success" path="/WEB-INF/pages/menu.jsp" />
        <forward name="failure" path="/WEB-INF/pages/login.jsp" />
    </action>

</action-mappings>

</struts-config>
========== end of /WEB-INF/struts-config.xml ==========

まずはフォームの種類と名前を登録する。
これは struts-config> の <form-beans> 内に、
<form-bean> 要素としてその定義を記述する。

name 属性には、フォームの名前、
type 属性には、フォームの FQCN が入る。
以降、このフォームを名前で識別する事ができるようになる。

次に、フォームをアクションに登録する。
フォームの内容を受け取るアクションが登録されている、
<action> 要素に対して属性を追加する。

name 属性には、使うフォームの名前を入れる。
この名前は、<form-bean> で定義したものだ。
これだけで、アクションにフォームが関連付けられる。

では、アクションの方も、このフォームを使うように
少し書き換えることにしよう。

========== LoginAction#execute ==========

    public ActionForward execute(ActionMapping mapping,
            ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {

        // フォームを、具体的な型にキャスト
        LoginForm f = (LoginForm)form;

        // ユーザ名は guest 限定とする
        if (!"guest".equals(f.getUser())) {
            return mapping.findForward(Forwards.FAILURE_KEY);
        }

        // パスワードは hogehoge 限定とする
        if (!"hogehoge".equals(f.getPassword())) {
            return mapping.findForward(Forwards.FAILURE_KEY);
        }

        // ログイン成功!
       
        // 「次回から入力を省略」にチェックがあれば
        if (f.isPersistent()) {
            // TODO: Cookie 等に情報を保存
        }

        // ログイン情報をセッションに保存
        request.getSession().setAttribute("user", f.getUser());

        return mapping.findForward(Forwards.SUCCESS_KEY);

    }

========== end of LoginAction#execute ==========

コードの見通しが良くなったことが分かるだろうか。

フォームは、execute メソッドに引数として渡される。
これは、ActionForm という汎用型になっているため、
具体的な型にキャストして使えばよい。

アクションにフォームを関連付けた場合、
Action#execute が呼び出される前に、
Struts によってフォームのインスタンスが作成され、
リクエストパラメータの値が設定が行われる。

値の名前や型はフォームのクラス情報から自動的に検出され、
パラメータ文字列から適切な型への変換が行われた後、
フォームの setter が呼び出されて値が登録される。

今回、チェックボックスが登場した。
チェックボックスの名前は persistent、
チェックされた時に送信される値は、y である。
チェックされなかった場合は何も送信されない。

もしチェックボックスの値を、
リクエストパラメータから取り出すとすれば、
request.getParameter("persistent") となるが、
その場合、その戻り値は「y」という文字列か null となる。

しかし、ActionForm を使えば、チェックボックスを、
boolean 型のパラメータとして扱う事ができる。

型を boolean として定義しておけば、
「y」や「on」、「1」、「yes」、「true」等の文字列は、
自動的に true に変換されて設定されるからだ。

y という文字列に対して比較するよりも、
明確に boolean に型付けられた変数を扱う方が、
コードがスマートになり、保守性が向上するのである。

この例は単純だったので、大差ないと感じるかも知れないが、
もちろん、ActionForm の機能はこれだけではない。
今後も ActionForm は Struts の要所要所で出てくるため、
後々その便利さが見えてくると思う。