使用有状态会话bean和servlet

use*_*191 9 ejb java-ee ejb-3.0

我正在尝试使用Glassfish Server(一个简单的购物车)的第一个EJB.我打算为每个Http Session使用CartBean.如果我的购物车豆跟随 -

public interface CartLocal {
 public void addItem(String item);
 public void removeItem(String item);
}

@Stateful
public class CartBean implements CartLocal {
 List<String> item = new java.util.ArrayList<String>();
 public void addItem(String item) {
  ....
 }
 public void removeItem(String item) {
  ....
 }
}
Run Code Online (Sandbox Code Playgroud)

我必须在web servlet客户端中使用上面的有状态会话bean,这样,对于每个新的Http Session,我们都会获得一个新的有状态会话bean.这样一个用户就有一个购物车.我的理解是错误的在servlet中使用会话bean,或者下面的代码是错误的,这为所有用户创建了一个有状态会话bean.

@EJB CartLocal cart;

protected void doGet(....) throws IOException...... {
 cart.addItem(....);
}
Run Code Online (Sandbox Code Playgroud)

Sha*_*dra 17

http servlet由该servlet的所有客户端共享,因此使用有状态会话bean注入它是不正确的,并且会导致不良影响.会话bean旨在用于每个客户端,它们通常存储在http会话中,以便该会话的所有请求都可以访问会话bean.您必须在doGet方法中使用jndi查找并将该引用存储在http会话中.存储后,您需要从http会话中检索并使用它.

更多信息

你有点不对劲.有状态会话bean类表示如何为有状态数据建模,这可能是细粒度相关类的图形.你从容器中请求一个statful bean(它创建/管理/激活/钝化它).这些服务是我们使用Stateful会话bean的.然而,容器不知道它所交换的任何对象属于哪个客户端.那么http会话就会出现.这部分是不应该强调的,因为它应该是你的困惑.Http Session是一个完美的存储位置,来自同一Web客户端的所有请求都可以访问存储在http会话中的所有属性.因此,您从容器中请求它并将其保存在某个位置(http会话),可以通过所有相同会话的请求再次引用它.现在想象一下非Web客户端的情况.在那里你没有http会话或类似的机制.您将不得不创建自己的存储机制来识别具有各自有状态bean的不同客户端.可能的方式可能是在某处存储有状态bean引用(比如在地图中将key作为clientId并将值作为bean引用),以及下次客户端想要访问bean时,它会传递clientId并从地图中获取它.

至于对有状态bean的http会话的偏好,重要的是理解http会话不是线程安全的.因此,如果您有一个ajax繁重的应用程序同时访问会话中的对象,您将不得不提供自己的同步机制,该机制将无法扩展,并将严重影响性能.在有状态会话bean的情况下,容器管理同步.

以下是关于使用http会话存储状态主题的有趣讨论.讨论是关于Brian Goetz的非常有用的文章"所有有状态的Java Web应用程序都被破坏了吗?".遗憾的是,我找不到IBM网站上的原始文章,但讨论主题提供了足够的材料来思考.

  • 这是[Brian Goetz的非常有用的文章"所有有状态的Java Web应用程序都被破坏了吗?"](http://www.ibm.com/developerworks/library/j-jtp09238.html) (2认同)