繁体   English   中英

JavaEE中的购物车困境

[英]The Shopping Cart dilemma in JavaEE

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

实际问题是购物车的实施。 有一次,购物车可以是SFSB(有状态会话Bean)。 这意味着EJB容器将servlet / web容器视为客户端并管理2个容器之间的对话。 如果EJB客户端是servlet / web容器,那么如何确定将项目添加到购物车的最终用户(实际客户端)?

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

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

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

谢谢。

实际上这是一个非常好的问题。

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

我遵循的两种方法(在最终决定两者之一之前):

  • 有状态会话EJB,实现定义业务逻辑的@Remote普通Java接口
  • SessionScoped ManagedBean和Stateless EJB实现了一个定义业务逻辑的@Local接口。

我个人从第一种方法开始,但我最近切换到第二种方法。 我将在后面的答案中解释原因。

第一种方法非常简单。 您只需要一个带有@Remote注释的简单接口和一个实现它的@Stateful会话Bean。 然后在您的支持bean中,您可以使用@EJB注释而不是@Inject注释来通过CDI注入接口,以利用EJB注入的所有@Inject功能,如池。 对于你的购物车,我会创建:

1)名为ShoppingCart.java的接口:

@Remote
public interface ShoppingCart{

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

}

2)实现ShoppingCart.java接口的名为ShoppingCartImpl.java的有状态会话EJB

 @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访问Statefull会话Bean。

public class ShoppingCartClient {

    @EJB
    private static ShoppingCart cart;

     // your methods here, using the ShoppingCart interface

}

实际客户与ShoppingCart实现实例的实例之间的实际“链接”得到保证,因为每个客户端都与有状态会话bean的新实例相关联。 从客户端的角度来看,业务方法似乎在本地运行,尽管它们在会话bean中远程运行。 对于记录...... Oracle在他自己的教程中提出了这种方法。

我喜欢的方法

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

1)Java Local接口

@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 Scoped 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以与存储状态会话Bean相同的方式存储会话范围的托管bean。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM