編集: これは壮大な手のひらの状況です。SessionScoped のインポートが正しくありません。昨夜チェック中にとても疲れていたので、面のセッションスコープのインポートをまだ使用している間に、エンタープライズのセッションスコープのインポートを使用していたと確信していました。私は私のような愚か者への援助としてこれを残しておきます. :)
このプロジェクトの初期段階です。マネージド Bean を使用してこの時点まで実装した後、マネージド Bean を CDI Bean に変更しました。これが最善の方法に関する最新のコンセンサスであるように思われるからです。私は一生、理由を理解できません。ヘルプとアドバイスをいただければ幸いです。
ハッピー パス (要約... コードの抜粋の下に詳細)
ユーザーがログインしていない場合は、ログインまたは登録リンクを表示します。
ユーザーがログインしている場合、ユーザー設定またはログアウト リンクを表示します。
CDIを使用したCrappy Path(CDIのせいではありません)
ユーザーがログインしていない場合は、ログインまたは登録リンクを表示します。
ユーザーがログインしている場合でも、ログインまたは登録リンクが表示されます。(悪い、悪いアプリ)
関連するオブジェクトは次のとおりです。
- ログインしているかどうかにかかわらずレンダリング属性を備えたfaceletメニューパネル(primefacesログインダイアログ付き...これはそれとは何の関係もないと思いますが、完全を期すために含まれています)
- セッション スコープのユーザー Bean、
- ユーザーをログインおよびログアウトするためのリクエスト スコープの認証 Bean。
使用したオブジェクトを以下に示します。CDI Bean として実装されます。
フェイスレット
<h:panelGroup id="loginPanel" rendered="#{!user.loggedIn}">
Show login buttons and stuff
</h:panelGroup>
<h:panelGroup id="logoutPanel" rendered="#{user.loggedIn}">
Show logout buttons and stuff
</h:panelGroup
認証 Bean
@Named(value = "webAuthenticationBean") //formerly managedbean
@RequestScoped
public class WebAuthenticationBean implements Serializable {
@Inject private UserBean user; //formerly a managed property which worked
...
request.login(uername, password);
user.setuserdata(username); // sessionscoped user state here used to check login state among other things later.
...
return(true) // they are now logged in
ユーザー Bean
@Named(value = "user") //formerly managedbean
@SessionScoped
public class UserBean implements Serializable {
@EJB
private UserService userService; //stateless session bean
private userInfo = new UserInfo(); // keeps user state and can be used as a DTO/VO
@PostConstruct
public void init() {
//sets default state to "guest user". This is NOT a logged in state
}
public void setuserdata(String username){
userInfo = userService.getUserInfo(username);
// method called from WebAuthenticationBean
// sets the user state to a non-guest user (they're logged in).
// I can see in debug mode that this is being called and retrieving
// the user data from the database and setting "userInfo"
}
public void isLoggedIn() throws InvalidUserException{
// checks state to see if they are logged in, basically a bit more than are they still a guest or not
returns (true) if logged in
returns (false) if not logged in
// this worked with managed beans
}
...
デバッグモードで見るときの実際の使用例は次のとおりです。
ハッピー パス (CDI Bean に変更する前)
1) ユーザーはようこそページに移動します
。2) ユーザー Bean は、ログインしているかどうかを確認するために照会されます (facelet の user.loggedIn)。
3) userbean はログイン状態をチェックします。彼らがまだゲストである場合、ログインしていません。
4) 彼らはゲストとして識別されるため、isLoggedIn() は false を返します。
5) ログインボタンが表示されます。
6) ユーザーがログインを要求します。
7) 認証 Bean がログイン プロセスを開始します
。request.login が正常に返されます。 8) authenticationbean がユーザー データを設定します。
9) 認証 Bean の loginMethod が返されます (それらはサーバー上で userprincipal に記録されます)
別の (くだらない) パスはここで分岐します (ハッピー パスが続きます)
10) メニューはログイン状態 (user.loggedIn)
を再チェックします 11) userbean は適切な状態をチェックし、有効な非ゲスト ユーザーであることを確認します
12) userbean は (true) を返し、ログインしています
13) メニューはログアウト ボタンを表示します
Crappy Path (これらを CDI Bean に変更した後に何が起こるか)
10) メニューはログイン状態を再チェックします (user.loggedIn)
11) userbean は適切な状態をチェックし、ゲストであることを確認します //更新されたユーザー状態は、このセッションでこのユーザーから消えたようです。
12) userbean が (false) を返します。 //ログインしていませんが、ログインしています。
13) メニューにログイン ボタンが表示されます。 -ユーザー ID が既に存在する間にログインします)。
マネージド Bean を使用すると、ユーザー Bean がセッション スコープでデータを維持しているのを確認できるのに、cdi Bean ではそうでないのはなぜですか? 私は困惑しています。必要に応じて管理対象の Bean に戻します。大きな問題ではありませんが、何を台無しにしたかを調べたいと思います。
UserBean の init メソッドにデバッグ コードを追加したところ、システムが SessionScoped UserBean を RequestScoped であるかのように扱っているように見えます。つまり、すべての呼び出しで初期化されています。
@PostConstruct
public void init() {
if (userInfo == null) {
userInfo = new UserInfoDTO();
userInfo.setUserName("Guest");
List<String> guestGroup = Arrays.asList(CoreUserGroupType.GUEST.toString());
userInfo.setUserGroups(guestGroup);
System.out.println("UserBean.init INSIDE Init If Statement");
}
System.out.println("UserBean.init OUTSIDE Init If Statement");
}
実際に SessionScoped のように動作している場合、userInfo オブジェクトは毎回 null になることはなく、'if' ステートメントは毎回実行されるわけではありません。ただし、UserBean へのすべての呼び出しで実行されています。したがって、これが問題の核心です。実際のところ、セッション スコープ内にあるように動作した場合、初期化されているため、すべての呼び出しで init メソッドにヒットすることはありません。
sessionscoped Bean を適切に作成していませんか? そのように見えますが、方法がわかりません。前述のように、このコードはマネージド Bean として定義されている場合は正常に実行されました。