簡體   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