使用有状态会话bean与servlet [英] Using stateful session beans with servlets

查看:110
本文介绍了使用有状态会话bean与servlet的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Glassfish Server(简单的购物车)尝试我的第一个EJB。我打算在每个Http Session中使用CartBean。如果我的购物车Bean正在关注 -

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

@Stateful
public class CartBean实现CartLocal {
列表< String> item = new java.util.ArrayList< String>();
public void addItem(String item){
....
}
public void removeItem(String item){
....
}
}

我必须在Web servlet客户端中使用上述有状态会话bean,对于每个新的Http Session,
,我们得到一个新的状态会话bean。所以一个用户有一个购物车。我的理解是错误的使用会话bean在servlet或下面的代码是错误的,这为所有用户创建一个有状态会话bean。

  @EJB购物车

protected void doGet(....)throws IOException ... {
cart.addItem(....);
}


解决方案

http servlet由该servlet的所有客户端都将其注册为有状态会话bean,这是不正确的,并会导致不良影响。会话bean是为每个客户端使用的,它们通常存储在http会话中,以便该会话的所有请求都可以访问会话bean。您将不得不在 doGet 方法中使用jndi查找,并将该引用存储在http会话中。一旦存储,您将需要从http会话中检索并使用它。



更多信息



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



就有关状态bean的http会话的偏好而言,重要的是了解http会话不是线程安全的。因此,如果您有一个ajax重的应用程序同时访问对象,您将必须提供自己的同步机制,这将使
不可扩展,并将大大影响性能。在有状态会话bean的情况下,容器管理同步。



这里是关于使用http会话来存储状态的主题的一个有趣的讨论。讨论在Brian Goetz的非常翔实的文章所有有状态的Java Web应用程序是否破损?。不幸的是,我找不到IBM网站上的原始文章,但讨论话题提供足够的材料来思考。


I am trying my first EJBs with Glassfish Server ( A simple shopping cart). I intended to use the CartBean for each Http Session. If my Cart Bean is following-

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) {
  ....
 }
}

I have to use the above stateful session bean in a web servlet client such that, for each new Http Session, we get a new stateful session bean. So that there is one shopping cart for one user. Is my understanding wrong of using session beans in servlet or the below code is wrong, this creates one stateful session bean for all the users.

@EJB CartLocal cart;

protected void doGet(....) throws IOException...... {
 cart.addItem(....);
}

解决方案

The http servlet is shared by all clients of that servlet so injecting it with a stateful session bean is not correct and will cause undesirable effects. Session beans are meant to be used per client and they are typically stored in http session so that all requests for that session can have access to session bean. You will have to use jndi lookup inside the doGet method and store that reference in http session. Once stored you would need to retrieve from http session and use that.

More Info

You are getting it a bit wrong. Stateful session bean class represents how you model your stateful data which could be a graph of fine grained related classes. You ask for a statful bean from the container (which creates/manages/activates/passivates it).These services are what we use Stateful session bean for. However container has no knowledge that whatever object it is handing over belongs to which client. So then the http session comes into picture. This part is what is not emphasised as much as it should be hence your confusion. Http Session is a perfect storage place where all request from same web client have access to all attributes stored in http session. So you ask for it from the container and keep it in a place (http session) from where it can be referred again by all requests for same session. Now imagine the case of non-web clients. There you do not have http session or similar mechanism. You will have to create a storage mechanism of your own to identify different client with their respective stateful beans.A possible way could be possibly storing the stateful bean reference somewhere ( say in a map with key as clientId and value as bean reference), and the next time client wants to access the bean it passes the clientId and gets it from the map.

As far as preference for http session over stateful bean is concerned, it important to understand that http session is not thread safe. So in case you have an ajax heavy application accessing an object in session simultaneously you will have to provide your own synchronization mechanism which will not be scalable and will impact performance heavily. In case of stateful session beans the container manages the synchronization.

Here is an interesting discussion on the topic of using http session for storing state. The discussion is on Brian Goetz's very informative article "Are All Stateful Java Web Applications Broken?". Unfortunately I cannot locate the original article on IBM site but the discussion thread gives enough material to ponder.

这篇关于使用有状态会话bean与servlet的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆