gpt4 book ai didi

java - JavaEE 中的购物车困境

转载 作者:搜寻专家 更新时间:2023-10-31 19:55:30 26 4
gpt4 key购买 nike

我正在使用 Java EE 堆栈开发在线商店。对于演示,我使用 JSF 2.2、用于持久性的 JPA 和用于业务逻辑的 EJB 3.x(其中 x >= 1)和用于服务的 JAX-RS,因为还将有一个移动应用程序。

实际问题是购物车的实现。在某一时刻,购物车可以是 SFSB(有状态 session Bean)。这意味着 EJB 容器会将 servlet/web 容器视为客户端并管理这两个容器之间的对话。 如果 EJB 客户端是 servlet/web 容器,我将如何识别将商品添加到购物车的最终用户(实际客户端)?

我的第二个选择是将 SFSB 存储到 HttpSession 中。这样,最终用户可以从 HttpSession 中检索购物车(并且该 session 已由 servlet 容器管理)。 这将如何影响 EJB 对话的事务状态?

购物车使用 JPA 保存在数据库中。

还有什么我需要考虑的吗?

谢谢。

最佳答案

其实这是一个很好的问题。

我 70% 的开发 Activity 都使用完全相同的堆栈(Java EE 7、Glassfish 4、JSF 2.2、EclipseLink JPA、EJB 3.1),而且我经常开发自定义电子商务网站,因此我熟悉购物车的设计。

我遵循的两种方法(在最终决定使用其中一种之前):

  • Stateful Session EJB,实现了定义业务逻辑的@Remote 普通 Java 接口(interface)
  • SessionScoped ManagedBean 和无状态 EJB 实现定义业务逻辑的 @Local 接口(interface)。

我个人是从第一种方法开始的,但最近我转向了第二种方法。我将在稍后的回答中解释原因。

第一种方法非常简单。您只需要一个带有 @Remote 注释的普通接口(interface)和一个实现它的 @Stateful session Bean。然后在您的支持 bean 中,您可以使用 @EJB 注释而不是 @Inject 注释通过 CDI 注入(inject)接口(interface),以利用 EJB 注入(inject)的所有优点,如池。我将为您创建购物车:

1) 一个名为 ShoppingCart.java 的接口(interface):

@Remote
public interface ShoppingCart{

public void init(Integer id);
public void addToCart(String product);

}

2) 一个名为 ShoppingCartImpl.java 的有状态 session EJB 实现了 ShoppingCart.java 接口(interface)

 @Stateful
public class ShoppingCartImpl implements ShoppingCart{

private Integer uid;
private ArrayList<String> products;

@PostConstruct
private void create(){
producs = new ArrayList<String>();
}

@Override
public void init(Integer id){
if(id==null){
uid = id;
}
}

@Override
public void addToCart(String product){
if(product!=null){
products.add(product);
}

}


}

客户端类可以通过 @EJB 注释使用 CDI 访问有状态 session Bean。

public class ShoppingCartClient {

@EJB
private static ShoppingCart cart;

// your methods here, using the ShoppingCart interface

}

物理客户与其 ShoppingCart 实现实例之间的实际“链接”是有保证的,因为每个客户都与一个有状态 session bean 的新实例相关联。从客户的角度来看,业务方法似乎在本地运行,尽管它们在 session bean 中远程运行。作为记录...Oracle 在他自己的教程中建议使用这种方法。

我的首选方法

我的首选方法是使用 SessionScoped JSF 支持 bean 表示代码,并使用无状态 EJB 来访问所需的业务逻辑。在这种情况下也需要一个接口(interface),但它可以是本地的,更改代码如下:

1) Java本地接口(interface)

@Local
public interface ShoppingCart{
public void doSomething(List<Product> list);
}

2) 无状态EJB

@Stateless
public class ShoppingCartImpl implements ShoppingCart{

@Override
public void doSomething(List<Product> list){
// persistence, tax calculation, etc
}
}

3) JSF session 作用域 Bean

@ManagedBean
@SessionScoped
public class CartBean {

private List<Product> products = new ArrayList<Product>();

public void add(Product product) {
products.add(product);
}

public void remove(Product product) {
products.remove(product);
}

public List<Product> getProducts() {
return products;
}
}

第二种方法有以下好处:

  • 无状态 EJB 比有状态 EJB 更快
  • 无状态 EJB 设计支持池化

内存占用与第一种情况相同,因为 JSF 以与有状态 session Bean 相同的方式存储 session 范围内的托管 bean。

如果您希望能够在其他地方使用它或在不同的 webapp 之间共享它们,则适合有状态的 EJB。

关于java - JavaEE 中的购物车困境,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20956169/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com