エラーメッセージ

現在のログイン画面には大きな問題がある。
利用者の入力に不備があった場合でも、
何もメッセージが表示されない所だ。

アクションの処理を見れば分かるが、ログインに失敗した場合、
何もせずに failure に転送している。
failure はログイン画面に転送するため、
結果的に、入力が無視されているように見えてしまう。

一般的には、入力に不備がある場合は、
その旨をエラーメッセージとして画面に表示し、
再度入力できるようにフォームを表示するべきだろう。

この場合、入力を検証するのは Model の役目だが、
エラーメッセージを表示するのは View の役目である。
そのため、何らかの方法を使って、
Model から View へ情報を渡す必要がある。

最も簡単な方法は、リクエスト属性を利用することだ。
リクエスト属性は、Servlet 間の転送でも保持されるので、
Struts のアクションで値を設定して転送すれば、
受け取った側の JSP でそれを読み出すことができる。

では、"errorMessage" というリクエスト属性を使って、
アクションから JSP にメッセージを渡してみよう。

まず、アクションを書き換える。

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

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

        // パラメータを取得
        LoginForm f = (LoginForm)form;

        // ユーザ名は guest 限定とする
        // パスワードは hogehoge 限定とする

        if (!"guest".equals(f.getUser())
                || !"hogehoge".equals(f.getPassword())) {

            request.setAttribute("errorMessage",
                    "ユーザ名またはパスワードが違います");
            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 ==========

これで認証に失敗した場合、リクエスト属性の
"errorMessage" に文字列が設定される。

では、JSP でこれを表示してみよう。

========== /WEB-INF/pages/login.jsp ==========
<?xml version="1.0" encoding="UTF-8" ?>
<%@ page contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8" %>
<!DOCTYPE html PUBLIC
        "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
        xml:lang="ja" lang="ja">

<head>
    <meta http-equiv="Content-type"
            content="text/html; charset=UTF-8" />
    <title>struts-test ログイン</title>
</head>

<body>
    <h1>ログイン</h1>
    <p style="color: red">
        ${errorMessage}
    </p>
    <form action="./login.do" style="line-height: 2">
        <div>
            ユーザ名:
            <input type="text" name="user" value="" />
        </div>
        <div>
            パスワード:
            <input type="password" name="password" value="" />
        </div>
        <div>
            <input type="checkbox" name="persistent" value="y" />
            次回から入力を省略
        </div>
        <div>
            <input type="submit" value="ログイン" />
        </div>
    </form>
</body>

</html>
========== end of /WEB-INF/pages/login.jsp ==========

今日は EL 式を使ってみた。
JSP 2.0 では、任意の位置に式を埋め込む事ができる。
${errorMessage} と書くことにより、
errorMessage 属性の内容を取り出すことができる。
属性が見つからなければ何も表示されない。

では、適当な入力で実行してみよう。
メッセージが表示された。