- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在使用 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),而且我经常开发自定义电子商务网站,因此我熟悉购物车的设计。
我遵循的两种方法(在最终决定使用其中一种之前):
@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;
}
}
第二种方法有以下好处:
内存占用与第一种情况相同,因为 JSF 以与有状态 session Bean 相同的方式存储 session 范围内的托管 bean。
如果您希望能够在其他地方使用它或在不同的 webapp 之间共享它们,则适合有状态的 EJB。
关于java - JavaEE 中的购物车困境,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20956169/
我正在使用 OneWayToSource绑定(bind),它似乎总是将我的源属性设置为空。为什么呢?这给我带来了麻烦,因为我需要源属性中目标属性的值而不是空值。 这是我的代码: MyViewModel
我有一个实例变量属性,它被声明和实例化,如下所示: $self->{properties}{$key1} = $value; 我的理解是这将声明属性字段,并将其设置为包含一个键值对的哈希原语。 我正
我正在尝试检查给定的数字是否是质数。首先采用试分割法。但该程序的行为很奇怪。这是我使用的。 int no; no = Integer.parseInt(jTextField1.getText());
我正在使用 NSUserDefaults使一个对象在多个 UIViewController 之间保持同步UITabbarController 中使用的 s .为此,我正在实现以下 - (void)vi
考虑以下 Java 方法: public Boolean compare(String val1, String val2) { return val1.length() > 0 && val
我有一个问题...假设我有一个包含城市名称的表。像这样: id name 1 Los Angeles 2 Madrid 我有一张用户表: uid username locationid
我无法理解这个问题。该代码非常基本,但它的行为却出乎意料。该代码是例程的简化版本,用于从每日数据库中提取每月第 15 天的数据并将其保存到单独的文件中。哪里有问题 ?第一个 cout 打印输入外部 i
我在 中使用大背景标签,我想制作一个宽度为 960px 的容器 div。我希望容器 div 位于从顶部向下 15px 的位置,我想我必须使用 position:absolute。我的困境是;容器内的
我遇到了一个难题。我有一个 hashedX 字段,它是一个散列值/加盐值,按照惯例,加盐值保存在 mysql 数据库的同一行中。 hashedX saltX ------ ---
类 java.io.Reader 和 java.io.InputStreamReader 都有具有完全相同签名的读取方法 public int read(char[] charbuf, int off
我有一个包含多个 C# 项目的 C# 解决方案。我打算在其中添加日志记录。此日志记录应该在所有项目中可用,并且最好使用带有滚动文件日志的 log4Net。 在上述前提下,我可以想到两种方法。 在解决方
我开始学习Python,目前我非常喜欢它。但是,如果你能帮我回答几个问题,这些问题一直困扰着我,我找不到任何明确的答案: 就语言兼容性而言,Python 的 C 实现(来自 python.org 的主
我正在尝试使用 AVAssetWriter 将 CGImages 写入文件以从图像创建视频。 我已经让它在模拟器上以三种不同的方式成功运行,但在运行 iOS 4.3 的 iPhone 4 上,每种方法
我需要对一个想法进行建模,可以将其分解并考虑如下: 图书详细信息 图书价格 这里的问题是您可以为书籍设置许多价格,并且这些价格可能会发生变化。这是一个例子 图书详细信息: --------------
我有一个表,其中的行包含名为 MySubId 的列。此列中的值可以重复。我想找到 MySubId 值和出现次数最多的 MySubId 值的行数。 我有以下查询: SELECT MySubId, COU
我有两个具有多对多关系的类,因此我在它们之间创建了一个联接表(一个非常经典的示例!) 在java+hibernate中我想知道哪种方式更好?使用hibernate多对多注释在这两个类之间有多对多关系吗
我正在尝试创建一个 Android 应用程序来完成以下任务:它通过短信向一组收件人(存储在数组中的数字)发送初始调查问题。然后,对于收到的每个响应,它都会向该参与者发送该系列中的下一个问题。这是我做过
这里有一个关于 IncludeEventHandler 的有趣问题。 我正在开发一个基于 Spring 的应用程序,该应用程序使用具有单独投资组合站点的不同供应商的速度。我让供应商通过向他们提供存储在
我真的无法理解事件和委托(delegate)的概念。我知道委托(delegate)是持有方法引用的对象,可以调用具有相同返回类型和参数的方法,但事件到底是什么? 如果我需要使用事件来制作一个简单的计算
在我正在处理的一个项目中,我有一个扩展 JFrame 的主类(名为 TrackWin)。在此框架中,我使用 JTabbedPane。 用户可以从菜单栏在 Pane 中创建新选项卡。每当发生这种情况时,
我是一名优秀的程序员,十分优秀!