メッセージ
概要
ウェブページ上で何らかの操作を起こしたとき、その結果をメッセージとして表示することはユーザーに安心感を与えます。 特に、何らかの原因で操作が実行されなかった場合、あるいはエラーが発生した場合、それは必須となります。
例として、入力フォームで記入漏れがあったためにその操作が実行されなかった場合、 エラーページを表示してエラーメッセージを表示し、ブラウザの「戻る」ボタンを使って戻ってもらうか、 もっと親切なアプリケーションであれば、再び入力フォームを表示して、そこにエラーメッセージを出すでしょう。
メッセージ
MessageHolder はユーザーに対してメッセージを表示するためのオブジェクトで、各種コンポーネントに必ず渡されます。 メッセージは次の2段階に分けられています。
- info
- 「○○を更新しました。」のような通常のメッセージです。
- invalid
- 「○○が制限×を超えています。」のような入力に対するエラーメッセージです。
MessageHolderには、メッセージのカテゴリー、例外オブジェクトと共にメッセージ文を追加することができます。 カテゴリーは、後でメッセージを画面に表示する際に、メッセージの表示場所を決めるために使います。
その他、特殊なメッセージとしてerrorメッセージがあります。 これは環境に起因する問題など、ユーザーの責任ではないエラーで、即座に画面に出力されます。
例外オブジェクトはロギングのために使います。 errorメッセージに対する例外はWARN(警告)レベルで、その他の例外はDEBUG(デバッグ)レベルでログに出力されます。
MessageHolderは独特のライフサイクルを持っています。 初期状態では何のメッセージも追加されていない状態です。 メッセージをいくつか追加すると、hasMessage,hasInvalid,hasErrorメソッドによってメッセージの存在が確認できるようになります。 しかし、その状態ではgetMessagesメソッドによってメッセージは取得できません。 追加されたメッセージは、commitメソッドを実行することで、getMessagesで取り出せるようになります。 このとき、逆にhasMessage,hasInvalidメソッドでメッセージの存在を確認できなくなります(常にfalse)が返ります。
例えばhasInvalidは、以下のように現在の処理で1度でも不正な入力やエラーがあったかを判別するために使うことができます。
public void act(Screen screen, MessageHolder mh, Map objectModel, String[] args) {
//パラメータ取得
...
//入力ミスのチェック
...
//不正な入力があれば処理を中断
if (mh.hasInvalid()) {
return;
}
}
MessageHolderのcommitを呼び出すために、 commit-messagesアクション が使うことができます。 また、messagesモジュール はgetMessagesによってメッセージを取り出すことができます。 これを、アクションと画面遷移の記述に利用すると便利です。
メッセージを出力するような処理...
@commit-messages;
$messages;
[
not-present: messages.invalid;
正常に処理を終えた場合...
]
[
present: messages.invalid;
不正な入力があった場合...
]
</cls:action>
MessageHolderの表示可能なメッセージは、commitメソッドを呼び出した後、 1回だけ次のページに引き継ぐことができます。 上記のアクションを実行した後、次のテンプレートを実行すると、invalidレベルのメッセージが全て表示されます。
<body cls:logic="$messages;">
<ol cls:logic="present: messages.invalid">
<li cls:logic="iterate: messages.invalid m;">${m}</li>
</ol>
</body>
カテゴリーを使うと、さらにカテゴリーごとにメッセージの表示場所を制御することが出来ます。 例えば、名前フィールドに関するメッセージを"name"というカテゴリーにして、 eメールフィールドに関するメッセージを"email"というカテゴリーにすると、 それぞれの入力フィールドの上に、対応するメッセージを表示できます。
<form cls:logic="$messages;">
<div cls:logic="iterate: messages.invalid.name m;">${m}</div>
名前:<input type="text" name="name" value=""/>
<div cls:logic="iterate: messages.invalid.email m;">${m}</div>
eメール:<input type="text" name="email" value=""/>
</form>

