我的应用程序中有一个要求,其中“N”个产品可以与报价相关联。屏幕布局将有两个部分。顶部有一个包含报价相关信息的表格,底部用于容纳多个产品。我通过在底部放置 iframe 来实现此功能。单击按钮(使用 javascript)将添加/删除产品。每个 Product 窗口中显示的内容将由相同的 Action (ProductLinesAction.java)、JSP (ProductLines.jsp) 和其他相关资源呈现。这里的要点是,只要在屏幕上加载新的产品窗口,就会创建该 Action 类的多个实例。我在加载窗口时没有问题,因为它只是准备要显示的表单。虽然要保存报价,所有这些产品表单都将被提交,我合并的逻辑是 1 到 N-1 个动作实例将表单值放入一个 VO 中,该 VO 添加到 Vector 对象并保存在会话中(以便其他动作实例可以接受它从会话并在其上添加)。第 N 个动作实例旨在共同保存所有这些产品值。业务规则验证也在保存之前执行,因此第 N 个操作实例将与错误一起可用,这些错误应该显示在每个产品窗口中。第 N 个动作实例旨在共同保存所有这些产品值。业务规则验证也在保存之前执行,因此第 N 个操作实例将与错误一起可用,这些错误应该显示在每个产品窗口中。第 N 个动作实例旨在共同保存所有这些产品值。业务规则验证也在保存之前执行,因此第 N 个操作实例将与错误一起可用,这些错误应该显示在每个产品窗口中。
为了确保所有其他操作实例也能利用与其窗口对应的错误,我实现了等待和 notifyAll 机制,当尝试保存超过 6 个产品时,事情就会出错。代码如下。这段代码适用于小于或等于 6 的产品(我的意思是最多 6 个动作实例)。加载并保存第 7 个产品时,第 7 个实例在调试模式下根本不可见或可追溯(提交表单时实例未达到预期方法)。
任何人都可以对这里犯下的导致这个问题的错误有所了解。
public String submitProducts()
throws Exception {
String resultValue = "";
/* Algorithm: */
// 1. Read the Vector object from Session.
// 2. Check whether the size of the Vector matches the Total Product windows count.
// 3. If yes, call the Save operation and remove the list from session.
// 4. If not, copy the values from current Action instance to VO.
// 5. Add to List object and place in session.
synchronized (productVOsInVector) {
productVOsInVector = getProductVOVectorFromSession();
if (productVOsInVector == null) {
productVOsInVector = new Vector <ProductVO>();
}
log.info("Window Number is " + activeWindowNumber + ". List size is " + productVOsInVector.size());
if (productVOsInVector.size() == (prodWindowCount - 1)) {
productVOsInVector = mapActionToVO(productVOsInVector);
resultValue = saveOperation(productVOsInVector);
if (resultValue.equalsIgnoreCase(SUCCESS)) {
session.put("OperationStatus", SUCCESS);
}
session.remove("productVOMapData");
}
else {
if (quoteSaveStatus) {
quoteSaveStatus = false;
}
session.put("OperationStatus", "");
productVOsInVector = mapActionToVO(productVOsInVector);
session.put("productVOMapData", productVOsInVector);
}
waitForOperationStatus();
}
System.out.println("Came out of sync block");
System.out.println("Action Instance" + activeWindowNumber + " is resuming.");
// Code to display the Error messages
return resultValue;
}
public void waitForOperationStatus() {
String opStatus = getOperationStatusFromSession();
synchronized (productVOsInVector) {
if (!opStatus.equalsIgnoreCase(SUCCESS)) {
try {
System.out.println("Window # " + activeWindowNumber + " Waiting");
productVOsInVector.wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
opStatus = getOperationStatusFromSession();
}
productVOsInVector.notifyAll();
}
}