POJOのActionでのAction#addErrors()

POJOのActionでもhtml:errorsタグで表示するメッセージを作りたいときがあるなーっと思って。


ユーザー情報で、すでに登録されているaccountで登録しようとしたら、やっぱり「そのアカウントはすでに登録されています。」って表示したい。
でも、そのエラーを別画面に表示するんじゃなくて、Strutsのvalidation機能と同じような雰囲気で。

そこでこうしてみました。
POJOのActionで

    public static final String messages_EXPORT = "errors";

    private Map messages = new HashMap();

    public Map getMessages() {
        return messages;
    }

こんな感じで、フィールドとgetterを宣言して、メッセージを表示したい場合は、POJOのActionのメソッド内で

    public String logon() {
        if (partyFacade.existParty(logonForm)) {
            return "logon";
        } else {
            messages.put("errors.logon", new Object[] {});
            return "logonError";
        }
    }

messages#put()を呼び出すっと。
"errors.logon"は、MessageのKeyとなるので
MessageResources.propertiesに記述する必要があって

errors.logon=アカウントまたはパスワードが違います。

new Object[] {}は・・・


これはActionMessageのコンストラクタをみればわかるから詳細はなし。

これでJSP

  <html:errors />

って書けばメッセージを表示できる。


こんだけ見ればよさそうだけど・・・欠点がね・・・


1つ目の欠点は

    private Map messages = new HashMap();

って実態をHashMapにしてるとこ。
これって複数登録したときに順番が保証できなくなる。
じゃぁ、順番を保証するMap実装使えばいいじゃんってことになるけど、そいうのを強制するのって嫌じゃない?なんとなくだけど。
気にする人だけ順番保証のMap実装を使えってことにすればいいのかなー。

あと、いっそActionMessagesにしてしまおうかとも思ったけど、せっかくorg.apache.struts.*のimport文をなくしたのにこんなことのためだけに入れたくはないよね。絶対。


2つ目の欠点は、結局中途半端なんところ。
したのような感じで

        Map mapErrors = (Map) var;
        ActionMessages errors = new ActionMessages();
        for (Iterator it = mapErrors.keySet().iterator(); it.hasNext();) {
            String key = (String) it.next();
            ActionMessage error = new ActionMessage(key, mapErrors.get(key));
            errors.add(ActionMessages.GLOBAL_MESSAGE, error);
        }

MapからActionMessagesに変換しているから、グループ(Property?)がActionMessages.GLOBAL_MESSAGEになってしまう。


これってさ、やっぱ中途半端だよねー。自分ではhtml:errorsタグしか使ったことがないから問題ないけど、html:messagesタグ利用している人は困るよね。やっぱり。


うーん。やっぱもっと考えよ。いい方法を。納得できたら提案してみよ。