13

Webアプリケーションを使用して各クライアントとの会話状態を追跡したい場合は、セッションBeanまたはHTTPセッションのどちらを使用するのが良いですか?

HTTPセッションの使用:

//request is a variable of the class javax.servlet.http.HttpServletRequest
//UserState is a POJO
HttpSession session = request.getSession(true);
UserState state = (UserState)(session.getAttribute("UserState"));
if (state == null) { //create default value .. }
String uid = state.getUID();
//now do things with the user id

セッションEJBの使用:

Webアプリケーションリスナーとして登録されたServletContextListenerの実装ではWEB-INF/web.xml

//UserState NOT a POJO this this time, it is
//the interface of the UserStateBean Stateful Session EJB
@EJB
private UserState userStateBean;

public void contextInitialized(ServletContextEvent sce) {
    ServletContext servletContext = sce.getServletContext();
    servletContext.setAttribute("UserState", userStateBean);
    ...

JSPの場合:

public void jspInit() {
    UserState state = (UserState)(getServletContext().getAttribute("UserState"));
    ...
}

同じJSPの本文の他の場所:

String uid = state.getUID();
//now do things with the user id

それらはほとんど同じであるように思われますが、主な違いは、UserStateインスタンスがHttpRequest.HttpSession前者ServletContextの場合と、後者の場合に転送されることです。

2つの方法のどちらがより堅牢で、なぜですか?

4

3 に答える 3

11

@BalusCが指摘したように、あなたの例では、EJBはすべてのクライアントで同じであり、必要なものではありません。

たとえば、ユーザーがログインしてセッションに保存するときにEJBを作成する場合など、これを変更してクライアントごとに1つのEJBを設定することもできます。

HttpSessionただし、とステートフルセッションBean(SFSB)の使用には、他にも微妙な違いがあります。特にこれらの2つ:

  1. 例外処理。トランザクションがEJBで失敗した場合、Beanは無効になり、使用できなくなります。これにより、Webアプリケーションのエラー処理戦略が複雑になる可能性があります。
  2. 並行性。同じSFSBに同時にアクセスすることはできないため、Webレイヤーで同期する必要があります。繰り返しますが、これは設計を複雑にする可能性があります。

詳細については、この回答を参照してください。サーブレットでのSFSBの正しい使用法

要約するHttpSessionと、私はあなたの場合、アプローチに賛成し、SFSBに反対することをお勧めします。SFSBは、それではできないことを提供する場合にのみ使用してください。そうHttpSessionではありません。

于 2010-05-11T13:31:11.597 に答える
3

ServletContextアプリケーションスコープを表します。アプリケーションスコープの属性は、すべてのセッションのすべてのリクエスト間で共有されます。それは「アプリケーション全体のグローバル」です。クライアント(つまり、セッション)固有の情報をそこに保存する必要はありません。新しいクライアントがログインすると、アプリケーションスコープ内の既存のEJBがクライアント固有のEJBで上書きされ、すべてのクライアントに反映されます。

セッションスコープはまさにこの目的のためのものです。それを利用してください。

于 2010-05-11T12:12:29.067 に答える
2

少し明確にするために、サーブレットコンテキストはサーブレットが作成されるときに初期化され(サーブレット仕様を参照)、そのインスタンスに固有のものです。サーブレットは、複数のスレッドを使用して同時クライアント要求を処理します。サーブレットコンテナは、サーブレットを作成または破棄するタイミングを決定し、クライアント要求を委任します。

これが、1つのサーブレットがn人のユーザー(n> = 1)の要求を処理することになり、上記のServletContextを使用したサンプルコードでは、すべてのユーザーがサーブレットの作成を引き起こしたユーザーのセッションBeanを共有することになります。

于 2012-01-11T16:01:40.203 に答える