2014-01-06 2 views
5

Я работаю в интернет-магазине, используя стек Java EE. Для презентации я использую JSF 2.2, JPA для сохранения и EJB 3.x для бизнес-логики (где x> = 1) и JAX-RS для служб, так как будет мобильное приложение.Дилемма корзины покупок в JavaEE

Актуальной проблемой является реализация корзины покупок. В какой-то момент Корзина может быть SFSB (Stateful Session Bean). Это означает, что контейнер EJB будет обрабатывать сервлет/веб-контейнер в качестве клиента и управлять разговором между двумя контейнерами. Как бы я тогда идентифицировал конечного пользователя (фактического клиента), который добавляет элементы в корзину покупок, если EJB-клиент является сервлетом/веб-контейнером?

Моим вторым вариантом является сохранение SFSB в HttpSession. Таким образом, конечный пользователь может получить корзину из HttpSession (и сеанс уже управляется из контейнера сервлета). Как это повлияет на транзакционные состояния разговора EJB?

Карточка покупок хранится в базе данных с использованием JPA.

Есть ли что-нибудь еще, что мне нужно принять во внимание?

Спасибо.

ответ

6

На самом деле это очень хороший вопрос.

Я использую тот же точный стек (Java EE 7, Glassfish 4, JSF 2.2, EclipseLink JPA, EJB 3.1) для 70% моей деятельности по развитию, и я часто разрабатываю пользовательские сайты электронной коммерции, поэтому я знаком с дизайн тележек для покупок.

двух подходов я следовал (прежде чем окончательно решить одну из двух):

  • Stateful Session EJB, реализующего простой интерфейс @Remote Java, который определяет businness логику
  • SessionScoped ManagedBean и Stateless EJB реализуя интерфейс @Local, который определяет бизнес-логику.

Я лично начал с первого подхода, но недавно перешел ко второму. Я объясню, почему, позже в этом ответе.

Этот первый подход очень прост. Вам просто нужен простой интерфейс с аннотацией @Remote и с его помощью можно использовать @Stateful Session Bean. Затем в фоновом режиме вы можете вводить интерфейс через CDI, используя аннотацию @EJB вместо @Inject, чтобы использовать все приятные функции инъекций EJB, таких как объединение. Для вас телеге я хотел бы создать:

1) это интерфейс с именем ShoppingCart.java:

@Remote 
public interface ShoppingCart{ 

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

} 

2) Stateful Session EJB с именем ShoppingCartImpl.java реализующий интерфейс ShoppingCart.java

@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); 
    } 

} 


} 

Класс клиента может обращаться к сеансовому компоненту Statefull с использованием CDI через аннотацию @EJB.

public class ShoppingCartClient { 

    @EJB 
    private static ShoppingCart cart; 

    // your methods here, using the ShoppingCart interface 

} 

Действительная «ссылка» между физическим клиентом и его экземпляром экземпляра реализации ShoppingCart уверен, потому что каждый клиент связан с новым экземпляром сессионного компонента. С точки зрения клиента, бизнес-методы работают локально, хотя они запускаются удаленно в сеансовом компоненте. Для записей ... Oracle в своих собственных учебниках предлагает такой подход.

предпочтительную ПОДХОД

Мой предпочтительный подход заключается в использовании бэк боб SessionScoped JSF, представляющий код, и используя Stateless EJB, чтобы получить доступ к необходимой бизнес-логики. Интерфейс необходим в этом случае, но это может быть сделано местное, изменение кода что-то вроде этого:

1) Java Локальный интерфейс

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

2) Stateless EJB

@Stateless 
public class ShoppingCartImpl implements ShoppingCart{ 

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

3) JSF Session Bean Scoped

@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; 
} 
} 

Второй подход имеет следующие преимущества:

  • Stateless EJB быстрее затем Stateful EJB
  • Stateless EJB поддержка пулы дизайн

Объем памяти такой же, как в первом случае, так как JSF хранит сеанс контекстными управляемые компоненты таким же образом Stateful Сессионные бобы хранятся.

Stateful EJB подходят, если вы хотите использовать его где-то в другом месте или делиться ими между различными webapp.

+1

Рассмотрите этот сценарий: у вас есть дополнительное приложение для Android, подключающееся к вашему приложению с помощью 'JAX-RS', и вам нужна корзина для покупок. Услуги такие же, как и в веб-приложении JSF. Используете ли вы SFSB или SLSB в корзине покупок? –

+0

Я бы использовал SLSB для мобильного приложения. Я разработал мобильные приложения, которые взаимодействуют с barebone serlvets, просматривая простые ответы JSON, созданные с использованием SLSB, вводимого через CDI (аннотации @EJB). – elbuild

+0

В вашем первом примере подхода вы храните «ShoppingCartClient» в качестве атрибута в объекте HttpSession, правильно? –

Смежные вопросы