2011-12-16 14 views
4

アプリケーション内に現在のユーザー情報を保持するために使用しているステートフルなEJBがあります。このEJBはサーブレットコントローラに注入され、最後にログインしたユーザを格納するために使用されます。しかし、セッションはすべての単一のクライアントで同じようです。ステートフルなEJBと同じセッションがクライアント間で複製されています

サンプルEJBコード:

Stateful 
@LocalBean 
public class CurrentUserBean { 

private string Username; 

public void setUser(String un) 
{ 
    Username = un; 
} 

.... 

サンプルサーブレットコード:アプリケーションは私のサーバーにデプロイし、私はいくつかの異なるクライアントからサーバーに話し、多くの異なる人々を持っている今

public class MainController extends HttpServlet { 
     @EJB private CurrentUserBean userBean; 

     protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 

       HttpSession session = request.getSession(); 
       String name = session.getAttribute("username"); 

       userBean.setUser(name); 
       ...... 

、ユーザー名は常に最後にログインしたユーザーに設定されます。つまり、ステートフルセッションBeanがすべてのクライアントで同じ状態を維持しているようです。私は、247ページからのJava 6 EEチュートリアルでは、以下の引用文を読んで、これは、大幅に私を混同:ステートフルセッションBeanで

、インスタンス変数は、一意のクライアント/豆のセッションの状態 を表します。クライアントは ( "talks")とBeanを対話するため、この状態は対話型 状態と呼ばれることがよくあります。その名前が示すように、セッションBeanは 対話セッションに似ています。セッションBeanは共有されません。対話型セッションには の1人のユーザーしか持たないのと同じ方法で、1クライアントを 人だけ持つことができます。クライアントが終了すると、そのセッションBeanは になり、クライアントに関連付けられなくなります。

これはなぜ起こっているのか誰かが説明し、ステートフルBeanをすべてのクライアントで同じ状態に保たない適切な方法で使用する方法を説明できますか?

ありがとうございます。

+0

あなたも別のHTTPセッションを取得したり、同じですか? – Thomas

+0

私がこれを見つけた唯一の方法は、ユーザーが誰か他の人としてログインしていると言って電話した後に、アプリケーションに飛びついて、同じユーザーと私はまだ認証されていませんでした。 – JCab

答えて

6

ステートフルセッションBeanにはユーザーごとの状態(実際にはセッション)がありますが、サーブレットには状態はありません。このように注入することで、このサーブレットでは単一のBeanが使用されます。これは、サーブレットの作成時に注入されるためです(おそらく、最初の訪問者に託されたBean)。

Beanを挿入するのではなく、processRequestメソッド内のコンテキストから取得する必要があります。

InitialContext ctx= new InitialContext(); 
CurrentUserBean userBean = (CurrentUserBean)ctx.lookup("CurrentUserBean"); 
+2

+1。サーブレットのインスタンスは1つだけ作成され、すべての要求は異なるスレッドの同じインスタンスによって処理されます。したがって、基本的に同じEJBインスタンスがすべてのクライアントによって共有されています。 –

1

それとも、

@Inject 
Instance<CurrentUserBean> currentUserBeanInstance; 

protected void processRequest(... 
    CurrentUserBean currentUserBean = currentUserBeanInstance.get(); 

を使用するだけのJava EE 6

+0

CDIも必要です。 –

関連する問題