0

ステートフル セッション Bean を使用して EJB 3.1 をプログラミングしようとしています。EJB とは何か、およびステートフル、ステートレス、シングルトンの違いを十分に理解する必要がありました。

しかし、私のステートフル Bean には奇妙な動作があります。シングルトンとして動作します!! つまり、複数のクライアント/ブラウザー/マシンから以下のサーブレット (ShoppingCartServlet) を呼び出すと、同じ Bean が返され、毎回同じ値がインクリメントされます。Bean がシングルトンであるため、「カウント」値はクライアントから共有されます。

分かりやすく教えてください!!

ここにコード。

サーブレット コード

@WebServlet(name="ShoppingCartServlet", urlPatterns="/shoppingCart")
public class ShoppingCartServlet extends HttpServlet {
    private static final long serialVersionUID = 2789580260930727133L;

    @EJB 
    private ShoppingCart shoppingCart;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int count = shoppingCart.increaseCount();

        HttpSession session = request.getSession();     
        session.setAttribute("count", count);

        String nextJSP = "/shoppingCart.jsp";
        RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(nextJSP);       
        dispatcher.forward(request, response);
    }
}

EJB コード

@Stateful
@LocalBean
public class ShoppingCart {

    private int count;  

    public int increaseCount() {
        count++;
        return count;
    }
}

サーブレットは WAR ファイルにパッケージ化され、EJB は JAR ファイルにパッケージ化されます。どちらも一意の EAR ファイルにデプロイされます。

編集:以下のようにサーブレット コードを変更しようとしましたが、呼び出しごとに新しいステートフル Bean が作成されるようになりました。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Context ctx = new InitialContext();         
    ShoppingCart  shoppingCart = (ShoppingCart) ctx.lookup("java:global/jeeapp/jeeapp-business/ShoppingCart!org.madbit.jeeapp.shopping.ejb.ShoppingCart");
    int count = shoppingCart.increaseCount();

    HttpSession session = request.getSession();     
    session.setAttribute("count", count);

    String nextJSP = "/shoppingCart.jsp";
    RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(nextJSP);       
    dispatcher.forward(request, response);
}
4

1 に答える 1

2

複数のリクエストに対して同時に再利用されるサーブレットの単一インスタンスがあります。したがって、注入されたのは同じステートフル Bean であり、すべてのリクエストで共有されています。

サーブレットのスレッド セーフのために、インスタンス変数ではなく、ローカル変数を使用することをお勧めします。したがって、クラス レベルで注入する代わりに、メソッドで Bean をルックアップできます。


編集 :

HttpSession今後のアクティビティのために、ルックアップによって取得した EJB インスタンスをオブジェクトに格納できます。そのため、同じインスタンスを毎回取得するのではなく再利用し、この方法で会話状態を維持します。

于 2012-12-18T05:58:15.417 に答える