SessionスコープのオブジェクトをEL式で参照する場合ではまったこと

今思うと全然たいしたことじゃないけど、ちょっとはまったのでその時試したことを書きます。

現象

SessionスコープのオブジェクトのpublicフィールドがEL式で参照できない。
getterを追加すると参照できる。

ユーザ情報を保持するDto

セッションとして保持するユーザ情報のDto
クラスに@Component(instance = InstanceType.SESSION)を設定。

jp.co.suusuke.dto.UserDto

public String code;

public String name;
ログインアクション

リダイレクトで社員側のトップページへ遷移する。
jp.so.suusuke.action.LoginAction

// ログインフォーム
@Resource(name = "loginForm")
@ActionForm
protected LoginForm form;

// ユーザ情報を保持するDto
public UserDto userDto;

// ログイン処理
@Execute(input = "login.jsp", redirect = true)
public String login() {

       ...

       userDto.name = name;

       ...

       // 社員側トップページ
       return "/syain";

}
社員側のトップページを表示するアクション

jp.co.suusuke.action.syain.IndexAction

@Execute(validator = false)
public String index() {
       return "index.jsp";
}
社員側のトップページ

syain/index.jsp

ようこそ ${userDto.name} さん
結果
javax.el.PropertyNotFoundException: Property 'name' not found on type jp.co.suusuke.dto.UserDto

UserDtoにgetterをつけると参照できて、リダイレクトしないでフォワードだと参照できた。

フォワードとリダイレクト時のリクエストスコープのインスタンスを画面に出力してみると、フォワード時はUserDtoがリクエストスコープのインスタンスに登録されている。

つまり、UserDtoをアクションのプロパティーに書いているので、フォワードだと取れるということ。getterをつけると取れるというのは実際にセッションスコープに登録されているUserDtoを参照しているため(publicフィールドには対応していない)

pageContext.findAttribute() したら、BeanWrapper が返ってきた。こ、これは!

ActionWrapper さんが、POJO Action のプロパティを色んなラッパーで包んでから HttpServletRequest に詰めてあげているのか。WrapperUtil#convert() が肝。ふむふむ。BeanWrapper は Map 実装だから、EL式でサラサラッとアクセスできる、ということかな?

http://d.hatena.ne.jp/deftrash/20080224/1203846804

ということですね。

アクションのプロパティは BeanWrapper に包んで、HttpServletRequest につめてるから publicフィールドの変数を EL式で参照できるようになるってことか。

結局、UserDtoにgetterつけることにしました。