5

こんにちは
私は現在Guiceと@SessionScopedで遊んでいます。もっとわかりやすくするために、(非常に単純な)認証プロセスを構築することにしました。

以下に、私が行った各ステップについて説明します。それでは、いくつか質問させていただきます。

[1] 人(ゲストまたはユーザー)を表すIdentityクラスを作成しました:

@SessionScoped
public class Identity implements Serializable
{
    private String uid;
    private String name;

    public boolean isAuthenticate()
    {
        return uid != null;
    }

    public void logout()
    {
        this.uid = null;
    }

    /*Setters-Getters*/
}

[2] 次に、ユーザーにログインする認証クラスを作成しました。

public class Authentication
{
    @Override
    public Identity authenticate(String login, String password)
    {
        /*some code*/

        Identity identity = new Identity();
        identity.setUid(user.getId());
        return identity;
    }
}

[3] 次に、サーブレットでユーザーにログインします。

@RequestScoped
public class LoginAction
{
    @Inject
    Injector injector;

    protected void login(HttpServletRequest req, HttpServletResponse resp)
    {
            Identity identity = injector.getInstance(Identity.class);
            Authentication auth = new Authentication();
            identity = auth.authenticate("login","password");
    }
}

[4] 最後に、ユーザーが認証されているかどうかを示すフィルターを作成します。

@Singleton
public class SecurityFilter implements Filter
{
    @Inject
    private Injector injector;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain)
    {
        Identity identity = injector.getInstance(Identity.class);

        if(identity.isAuthenticate())
        {
            System.err.println("USER");
        }
        else
        {
            System.err.println("GUEST");
        }

        chain.doFilter(request, response);
    }
}

まあ、このコードは機能していません。私のIDのuidは常に「null」です。

質問に行きましょう:

a-まず第一に、なぜ私のコードが機能しなかったのですか?
b-@ SessionScopedは、HttpSessionでオブジェクトを設定することと同等ですか?
c-(http)セッションでIdentityオブジェクト(それのみ)を無効にする方法は?
d-一般的に、どの場合に@SessionScopedを使用する必要がありましたか?

読んでいただきありがとうございます、
あなたの答えを待っています。

4

1 に答える 1

9

[a] Guiceが管理するインスタンスを置き換えるのではなくIdentity、のローカル変数にの新しいインスタンスを割り当てています。Guiceが管理する既存のインスタンスにフィールドとフィールドを入力LoginActionすることで問題を解決できます。uidnameIdentity

たとえば、代わりに

identity = auth.authenticate("login","password"); 

あなたは言えた:

Identity identity = injector.getInstance(Identity.class);
Authentication auth = new Authentication();
Identity authenticated = auth.authenticate("login","password");
identity.setUid(authenticated.getUid());
identity.setName(authenticated.getName());

それを行うためのよりクリーンな方法がありますが、あなたはその考えを理解します。

[b] / [d]その通りです:@SessionScopedに変数を設定するのと同じでHttpSessionあり、これはあなたがそれを使用するような状況です。セッション間で一意である必要があるが、すべてのリクエストで使用可能である必要があるオブジェクトに必要です。

[c]意味がよくわかりませんが、ユーザーがログインしているかどうかに応じてアプリ内の別の場所にリダイレクトする場合は、フィルターの設計が一般的な方法です。

あなたが行うことができるいくつかの改善:

  • SessionScopedセッションのユーザーを管理するサービスを用意し、インスタンスIdentityで同期されていることを確認します。Identityそうすれば、ユーザーが2つのリクエストをすばやく連続して行った場合でも、同時実行の問題が発生することはありません。
  • クラスをGuiceから切り離すために、(ここでの例)をProvider注入する代わりにsを注入することをお勧めします。Injector
  • フィールドを注入する代わりに、クラスのコンストラクターに依存性を注入します。これにより、テストが容易になります(テストでモック/スタブの依存関係を提供することにより)。
于 2011-04-25T10:49:29.457 に答える