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"; }
結果
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つけることにしました。