[Seasar-user:19662] セッション間のコンポーネントについて

TAKEUCHI, Manabu [E-MAIL ADDRESS DELETED]
2010年 4月 27日 (火) 16:35:40 JST


初めまして。竹内と申します。

今回、調査目的で Teeda ベースのサンプルアプリケーション (住所録) を作成しております。

Seaser 関係は C# で S2Dao.NET などを利用させておりましたが、Java では初めてです (Java では Struts
を利用していました)。

利用しているライブラリは次の通りです。

s2-framework: 2.4.41
s2-extension: 2.4.41
s2-tiger: 2.4.41
Teeda : 1.0.13-sp9

今回嵌っておりますのはセッション内の DTO の共有です。

セッションで共有する DTO を addressbook.dto.SessionDto とし、@Component(instance =
InstanceType.SESSION) で宣言してあります。

ログイン画面で承認されたユーザ情報をこの SessionDto に保存して、住所録の一覧ページなどを表示させる際にインターセプト
(LoginInterceptor) してユーザ情報が有効か、タイムアウトなど発生していないかを確認しております。

ここまでは無事に出来ました。

さらに、利用者管理画面を作成して、そのページに進入するには管理者権限のユーザのみに限定させようと思い UserListPage
のスーパクラス AbstractUserPage に sessionDto を DI して、prerender()
でユーザの管理者権限を確認し、ない場合はエラーページにリダイレクトさせようと思っておりました。

が、何故か DI される sessionDto にはログイン時に設定されているはずのユーザ情報が含まれていないのです
(まるで、別セッションのインスタンスが DI されているかのようです)。

もちろん、そのページを表示時にインターセプトしている際には、ちゃんと正常な情報が DI されています。

なぜ、LoginInterceptor と違う sessionDto が DI されるのでしょうか? また、同じ sessionDto を
DI されるにはどうしたらよいのでしょうか?

宜しくお願いいたします。


なお、ソースは次の様な感じです。

### addressbook.dto.SessionDto
@Component(instance = InstanceType.SESSION)
public class SessionDto implements Serializable {
    private User loginUser; // ログインしたユーザ情報
}


### addressbook.entity.User (Dolting で自動作成)
public class User {
    private BigDecimal id;
    private String loginId;
    private String password;
    private boolean administrator;
}


### addressbook.interceptor.LoginInterceptor
public class LoginInterceptor extends AbstractInterceptor {
    private SessionDto sessionDto; // これは正常に DI される。

    ... 以下略 ...
}


### addressbook.service.LoginService
public class LoginService {
    private UserDao userDao; // これは何故か DI されず、null のまま
    private SessionDto sessionDto;  // これも正常に DI されている。

    public User tryLogin(String loginId, String password) {
        User user = userDao.selectByLoginId(loginId);
        if (user == null || !user.getPassword().equals(password)) {
            user = null;
        }
        sessionDto.setLoginUser(user);  // ここでログイン ユーザ情報を設定
        return user;
    }
}


### addressbook.web.login.LoginPage
public class LoginPage {
    private UserDao userDao; // 正常に DI されている。

    public Class<?> doLogin() {
        loginService.setUserDao(userDao); // 何故か DI されないのでここで設定
        User user = loginService.tryLogin(loginId, password);
                if (user != null) {
                        return PersonListPage.class; // 住所録の一覧ページへ
                }
                return null;
        }
}


### addressbook.web.user.AbstractUserPage (Dolting で自動作成)
public abstract class AbstractUserPage extends AbstractCrudPage {
    protected SessionDto sessionDto; // これは DI されるけど別セッションの情報か?
loginUser は null のまま。
}


### addressbook.web.user.UserListPage (Dolting で自動作成)
public class UserListPage extends AbstractUserPage {
    public Class<?> prerender() {
        if (sessionDto.getLoginUser() == null ||
!sessionDto.getLoginUser().getAdministrator()) {
            // loginUser は常に null なので、エラーページへ
            return ErrorNoAdminPage.class;
        }
        ... 以下略 ...
    }
}


### app_aop.dicon
    <!-- 追加部分 -->
    <component class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
      <property name="autoNaming">
        <component
class="org.seasar.framework.container.autoregister.DefaultAutoNaming"
/>
      </property>

      <initMethod name="addClassPattern">
        <arg>"addressbook.interceptor"</arg>
        <arg>".*Interceptor"</arg>
      </initMethod>

      <initMethod name="addClassPattern">
        <arg>"addressbook.dto"</arg>
        <arg>".*Dto"</arg>
      </initMethod>

      <initMethod name="addClassPattern">
        <arg>"addressbook.service"</arg>
        <arg>".*Service"</arg>
      </initMethod>
    </component>


-- 
竹内 学 <mailto:[E-MAIL ADDRESS DELETED]>
株式会社エールシステム


Seasar-user メーリングリストの案内