当前位置: 首页 > 知识库问答 >
问题:

Http会话setAtort并不总是插入新对象

夏侯航
2023-03-14

我正在从WLS10g和JavaEE6升级到WLS12c和JavaEE7。

我注意到HttpSession.set属性的工作方式不同。在WLS10中,任何已经存储在某个键下的对象都将始终被替换。

在WLS12中,如果新建对象,则不会替换该对象。等于(旧对象)。

这对我们来说是个问题,因为应用程序有如下对象:

class ValueObject {
    int key;
    String data;

    @Override
    public int hashCode()
    {
      return key;
    }

    boolean equals(Object o) {
        if (o == null || (o instanceof ValueObject) == false) {
            return false;
        }
        ValueObject otherObject = (ValueObject)o;
        /* Return true if the keys are equal, even though the data may differ */
        return key == otherObject.key;
    }
}

ValueObject通过跨多个网页的工作流进行修改。中间值存储在HTTPStion中,并在工作流结束时将修改后的值写入数据库。

在servlet中有这样的代码(成员实际上是通过getter/setters修改的,但我正在简化以减少问题中的代码量):

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
    HttpSession session = request.getSession();
    ValueObject newValue = new ValueObject();
    newValue.key = Integer.parseInt(request.getParameter("key"));
    newValue.data = request.getParameter("data");
    session.setAttribute("value", newValue);
    ...

<代码>新值。键在新值时未被修改。数据具有新值。

WLS12中Http会话的修改行为打破了这种模式-当从会话中检索对象时,我们从第一步获取数据,因为当我们尝试存储更新版本时,对象不会被替换。

我们可以通过更改以下所有更新来解决此问题:

session.setAttribute("value", newValue);

session.removeAttribute("value");
session.setAttribute("value", newValue);

然而,有100多个servlet,因此这是一项大量的工作。这种变通方法既难看又容易出错,因为程序员在编写代码时还需要跟踪另外一件事。

有没有办法将WLS12c配置为使用旧行为,其中对象总是被HttpSession替换。setAttribute()?

更新2015-09-30:

提交给Oracle的错误报告。我已经尝试了wero建议的过滤器想法。似乎Weblogic希望进入过滤器链的对象属于类weblogic.server.internal.ServletRequest estImpl,因为当我包装它并将包装器发送到过滤器链时,我从内部Weblogic类获得了一个ClassCastException。

我还检查了Gimby建议的配置选项。我找不到任何适用于该课程的选项。我们部署到单个服务器,并使用内存作为会话持久性设置。

更新2016-02-03:

Oracle已将错误报告关闭为“非错误”。

共有2个答案

罗鸿福
2023-03-14

不是对您关于解决方法的问题的回答,而是会话的Javadoc。setAttribute对行为非常清楚:

使用指定的名称将对象绑定到此会话。如果已将同名对象绑定到会话,则会替换该对象。

所以你总是可以提交一个bugreport。

解决方法可以使用过滤器安装wrapped的HttpServletRequest,它返回一个wrapped的HttpSession,覆盖setAttribute,并实现先替换后设置逻辑。

童宏富
2023-03-14

由于Oracle以“不是bug”的形式关闭了bug报告,我决定实施变通方法。

我完成了对HttpSession的所有调用。并确定哪些调用使用了可能触发错误的对象。

在那些被我取代的地方

session.setAttribute(key, newValue);

session.removeAttribute(key);
session.setAttribute(key, newValue);

以及解释为什么需要额外的线的评论。

 类似资料:
  • 我想使用Drools规则进行一些验证: 我第一次创建了一个Statefull-KieSession,它第一次按预期工作。然而,当我重新运行该规则时,验证事实仍在内存中,这不是我想要的。因此,我尝试将示例调整为无状态KieSession。 使用KieSession K会话: 使用无状态KieSession会话: statefull会话在validations集合中返回一个Validation对象,无

  • 我目前正在将一个JavaEE5(WL10.3.5)应用程序迁移到JavaEE7(WL12.2.1),我面临一个奇怪的问题。 方法HttpSession的WebLogic 12c实现。如果对象相同(根据WL12c的实现相同),setAttribute(字符串,对象)不会用新对象替换绑定到同一字符串键的旧对象。 经过多次测试后,当您想替换会话中的对象时,WL12c比较哈希代码如果它们相同,它会比较对象

  • 问题内容: 我有一个简单的测试,尝试在其中更新对象,但是合并似乎在执行插入操作而不是更新操作。 } 这是我的更新方法 更新代码 现在,我收到以下错误无法提交JPA事务;嵌套的异常是javax.persistence.RollbackException:标记为rollbackOnly的事务 问题答案: 我有一个版本列,当种子数据插入数据库时​​未设置该列。因此,所有有关更新和删除的问题

  • Spring Boot 2.4.0,DB是MySql 8。 使用REST每15秒从远程获取数据并使用将其存储到MySql DB。 它为所有给定的实体调用save()方法。 所有数据都设置了ID。 我希望如果DB中没有这样的id-它将被插入。 如果这样的ID已经在DB中呈现-它将被更新。 这里是从控制台剪下的: 下面是获取和保存的方法,如下所示: 此方法每15秒运行一次。 实体: 和存储库: 这是以

  • 当试图更新现有的Django模型对象时(使用< code>save()方法),会插入一个新行。 例如: 在第二次调用< code>save()方法之后,一个重复的条目被插入到我的表中。 以下是模型定义的示例:

  • 问题内容: 我试图通过在会话中设置项目列表来将它们发送到JSP。我在这里使用Spring控制器。 会话对象包含所有三个项目。 问题: 预期: 会话对象应包含3个项目。 实际: 会话中只有2个项目可用,因为删除了第三个项目更新了会话对象。但是我从未将更新的l对象添加到会话中。为什么Java在返回页面之前重新分配会话对象?因此,我是否需要将l复制到另一个列表并使用它? 问题答案: 您必须首先了解Jav