Servlets 如果替换了servlet属性,则该属性的值

Servlets 如果替换了servlet属性,则该属性的值,servlets,servlet-listeners,Servlets,Servlet Listeners,这是我正在读的书: 从另一个有效的HttpServlet中获得此代码 已注册为ServletRequestAttributeListener: 生成了什么日志输出 答案是: C.A:A->b p:A->b M:A->C 书中的解释是: 狡猾!getValue方法返回属性的旧值,如果 属性已被替换 我的问题是这怎么可能? 特别是这部分顺序我不清楚:P:a->b 为什么会再次出现P:a->b而不是P:a->c?您混淆了属性的值,以及表示属性值已被替换的事件的值 当你打电话的时候 req.setAtt

这是我正在读的书:

从另一个有效的HttpServlet中获得此代码 已注册为ServletRequestAttributeListener:

生成了什么日志输出

答案是:

C.A:A->b p:A->b M:A->C

书中的解释是:

狡猾!getValue方法返回属性的旧值,如果 属性已被替换

我的问题是这怎么可能? 特别是这部分顺序我不清楚:P:a->b
为什么会再次出现P:a->b而不是P:a->c

您混淆了属性的值,以及表示属性值已被替换的事件的值

当你打电话的时候

req.setAttribute("a", "c");
请求创建一个新事件并激发它。因此,代码基本上如下所示:

public void setAttribute(String name, Object newValue) {
    // 1. get the old value
    Object oldValue = getAttribute(name);

    // 2. construct an event containing the old value
    ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(context, request, name, oldValue);

    // 3. store the new value of the attribute
    this.attributeMap.put(name, newValue);

    // 4. call all the listeners with the event
    for (ServletRequestAttributeListener listener : listeners) {
        listener.attributeReplaced(event);
    }
}
我找到了一个解释:

getName()方法返回触发事件的属性的字符串名称。getValue()方法返回触发事件的属性的对象值。小心它返回旧值,而不是新值。换句话说,它返回属性在触发事件的更改之前的值

所以它正在做我认为它应该做的事情,只是没有按照我期望的顺序(先改变值,然后触发事件)

更详细的解释是:

为了澄清这个输出,我们可以称之为“添加”、“替换”和“替换”吗 “已删除”,因此我们正在查看以下内容:

添加:a->b替换:a->b删除:a->c

现在的问题是,为什么替换后的值返回“b” “c”的意思

答案很简单,因为医生说它应该这样做:

无效属性放置(ServletRequestAttributeEvent srae)接收 已在上替换属性的通知 ServletRequest。参数:srae-ServletRequestAttributeEvent 包含ServletRequest以及 被替换的属性

现在也许更有趣的问题是他们为什么要这么做

通常像这样的API是用来传递旧值的, 因为您始终可以选择在 回拨。因此,如果他们把旧的价值传递给你,你会得到更多 您可获得的信息比他们刚刚传入当前 价值(没有办法问“这个属性使用了什么值 有吗?“在它消失之后”

因此,使用这种API设计,您可以编写一个侦听器,而不必花费一些时间 每当删除“a:b”时的操作-通过显式删除 调用或将其替换为另一个值。如果他们能通过的话 如果输入新值,则无法编写该侦听器(如果不存储 您自己添加的值)

希望这有助于澄清为什么会这样


谢谢你的及时回答,但恕我直言,我不认为我混淆了属性的价值和事件的价值。请参阅我在提供的答案中找到的解释。
public void setAttribute(String name, Object newValue) {
    // 1. get the old value
    Object oldValue = getAttribute(name);

    // 2. construct an event containing the old value
    ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(context, request, name, oldValue);

    // 3. store the new value of the attribute
    this.attributeMap.put(name, newValue);

    // 4. call all the listeners with the event
    for (ServletRequestAttributeListener listener : listeners) {
        listener.attributeReplaced(event);
    }
}