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

时间:2015-02-01 17:20:37

标签: servlets servlet-listeners

这来自我正在阅读的书:

  

给出来自其他有效的HttpServlet的代码   注册为ServletRequestAttributeListener:

public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
         req.setAttribute(“a”, “b”);
         req.setAttribute(“a”, “c”);
          req.removeAttribute(“a”);
}
        public void attributeAdded(ServletRequestAttributeEvent ev) {
        System.out.print(“ A:” + ev.getName() + “->” + ev.getValue());
}
       public void attributeRemoved(ServletRequestAttributeEvent ev) {
       System.out.print(“ M:” + ev.getName() + “->” + ev.getValue());
}
       public void attributeReplaced(ServletRequestAttributeEvent ev) {
       System.out.print(“ P:” + ev.getName() + “->” + ev.getValue());
}
  

生成什么日志输出?

答案是:

  

℃。 A:a-> b:a:> b M:a-> c

书中的解释是:

  

棘手! getValue方法返回属性if的OLD值   该属性已被替换。

我的问题是这是怎么回事? 特别是这部分序列对我来说并不清楚: P:a-> b 为什么再一次 P:a-> b 而不是 P:a-> c

2 个答案:

答案 0 :(得分:0)

您会混淆属性的值,以及事件的值,它表示已替换属性值。

致电时

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

答案 1 :(得分:0)

我找到了解释:

  

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

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

更详细的解释是这个:

  

为了澄清这个输出,我们可以称之为"添加","替换"和   "删除"所以我们正在考虑这个:

     

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

     

现在问题是为什么替换回来" b"换取价值   " c"?

     

简单的答案是因为那是文档所说的应该做的事情:   http://docs.oracle.com/javaee/7/api/javax/servlet/ServletRequestAttributeListener.html

     

void attributeReplaced(ServletRequestAttributeEvent srae)接收   通知已更换属性   ServletRequest中。参数:srae - ServletRequestAttributeEvent   包含ServletRequest以及的名称和(旧)值   被替换的属性

     

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

     

通常这样的API旨在传递旧的价值,   因为你总是可以选择询问当前的值   打回来。因此,如果他们通过你的旧价值 - 你有更多   您可以获得的信息,而不是他们刚刚通过的信息   值。 (没有办法询问"这个属性使用了什么价值   有&#34?;它消失后。)

     

因此,使用此API设计,您可以编写一个监听器而不是一些监听器   每当" a:b"被删除 - 通过显式删除   打电话或用另一个值替换它。如果他们只是传入   新的价值,你不能写那个听众(没有存储   自己添加的值。)

     

希望通过这种方式帮助更清楚。