37

我正在阅读 head first JSP 和 servlet。通过不同类型的听众,我遇到了HttpSessionBindingListenerHttpSessionAttributeListener

我在考虑两者之间的区别——我想看看这两个听众在现实世界的例子中的实际用法。我HttpSessionBindingListener通过实现valueBound()进行了测试valueUnBound()- 为什么对象需要知道它是否已添加?

我对实际用途感到很困惑。请帮助澄清这一点。

4

1 回答 1

51

HttpSessionBindingListener在其实例可能存储在会话中的类上实现,例如登录用户。

例如

public class ActiveUser implements HttpSessionBindingListener {

    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        logins.add(this);
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        logins.remove(this);
    }

}

当 this 的实例ActiveUser被 设置为会话属性时HttpSession#setAttribute()valueBound()将调用 。当它被 删除HttpSession#removeAttribute(),或会话无效,或被另一个 替换时HttpSession#setAttribute()valueUnbound()将调用 。

以下是一些真实世界的用例:

HttpSessionAttributeListener被实现为应用程序范围@WebListener当在. 继续上面的例子,如果你不能修改要实现的类(因为它是第 3 方左右),或者当你想在任意数量的类上使用“标记接口”时,这特别有用,这样您可以在一个中央位置完成聆听工作。HttpSessionActiveUserActiveUserHttpSessionBindingListener

@WebListener
public class ActiveUserListener implements HttpSessionAttributeListener {

    @Override
    public void attributeAdded(HttpSessionBindingEvent event) {
        if (event.getValue() instanceof ActiveUser) {
            logins.add(event.getValue());
        }
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent event) {
        if (event.getValue() instanceof ActiveUser) {
            logins.remove(event.getValue());
        }
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent event) {
        if (event.getValue() instanceof ActiveUser) {
            logins.add(event.getValue());
        }
    }

}

这是一个真实的用例:

于 2013-07-21T20:52:31.517 回答