JobPlus知识库 IT 软件开发 文章
web的监听器,你需要知道这些.

一、 简介

Listener是Servlet规范的另一个高级特性, 它用于监听java web程序的事件, 例如创建、 修改、 删除session, request, context等, 并触发相应的处理事件, 这个处理事件是由web容器回掉的。

学过安卓开发的同学一定很熟悉view.setonClickLister();

这样的对安卓控件的监听。 java web也是这样的, 根据不同的listner 和不同的event, 可以完成相应的处理事件。

二、 Listerner的分类

Listerner分为八种, 前三种是用于监听对象的创建和销毁, 中间三种用于监听对象属性的变化, 后两种用于监听Session内对象。

httpSessionListner: 监听session的创建与销毁, 用于收集在线用户信息。

servletContextListener: 监听context的创建与销毁, context代表当前web应用, 该listener可用于启动时获取web.xml的初始化参数。

servletRequestListener: 监听request 的创建与销毁。

httpSessionAttributeListener 监听session的种属性变化

ServletContextAttributeListener

ServletRequestAttributeListener

HttpSessionBindingListener, 监听对象存入或者移除 session

httpSessionActivationListener, 钝化和重新加载 session的监听

三、 监听session、 request、 servletContext

直接上代码, 下面监听了这三个对象创建销毁。

public class ListenerTest implements HttpSessionListener, ServletContextListener, ServletRequestListener {

Log log = LogFactory.getLog(getClass());

public void requestDestroyed(ServletRequestEvent sre) {

HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();

long time = System.currentTimeMillis() - (Long) request.getAttribute("time");

log.info("请求处理时间" + time);

}

public void requestInitialized(ServletRequestEvent sre) {

HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();

String uri = request.getRequestURI();

uri = request.getQueryString() == null ? uri : (uri + "?" + request.getQueryString());

log.info("ip" + request.getRemoteAddr() + uri);

request.setAttribute("time", System.currentTimeMillis());

}

public void contextDestroyed(ServletContextEvent sce) {

ServletContext servletContext = sce.getServletContext();

log.info("关闭:" + servletContext.getContextPath());

}

public void contextInitialized(ServletContextEvent sce) {

ServletContext servletContext = sce.getServletContext();

log.info("启动:" + servletContext.getContextPath());

}

public void sessionCreated(HttpSessionEvent se) {

HttpSession session = se.getSession();

log.info("创建:session:" + session.getId());

}

public void sessionDestroyed(HttpSessionEvent se) {

HttpSession session = se.getSession();

log.info("销毁建:session:" + session.getId());

}

}

需要在web.xml中配置: < listener > < listener - class > com.forezp.listener.ListenerTest < /listener-class> </listener >

四、 监听对象属性的变化

httpSessionAttributeListener 监听session的种属性变化

ServletContextAttributeListener

ServletRequestAttributeListener

以上三种方法用于监听session, context, request的属性发生变化, 例如添加、 更新、 移除。

下面以session的属性变化为例子:

public class SessionAttributeListener implements HttpSessionAttributeListener {

Log log = LogFactory.getLog(getClass());

public void attributeAdded(HttpSessionBindingEvent se) {

HttpSession httpSession = se.getSession();

log.info("新建属性:" + se.getName() + "值:" + se.getValue());

}

public void attributeRemoved(HttpSessionBindingEvent se) {

HttpSession httpSession = se.getSession();

log.info(" 删除属性:" + se.getName() + "值:" + se.getValue());

}

public void attributeReplaced(HttpSessionBindingEvent se) {

HttpSession httpSession = se.getSession();

log.info(" 修改属性:" + se.getName() + "原来的值:" + se.getValue() + "新值:" + httpSession.getAttribute(se.getName()));

}

}

web.xml配置, 此处省略。

五、 监听session内的对象

HttpSessionBindingListener, 当对象被放到session里执行valueBond();

当对象被移除, 执行valueUnbond();

httpSessionActivationListener, 服务器关闭, 会将session的内容保存在硬盘里, 这个过程叫钝化; 服务器重启, 会将session的内容从硬盘中重新加载。 钝化时执行sesionWillPassivate(), 重新加载sessionDidActivate();

举个例子:

public class User implements HttpSessionBindingListener, HttpSessionActivationListener, Serializable {

private String username;

private String password;

public void valueBound(HttpSessionBindingEvent httpsessionbindingevent) {

System.out.println("valueBound Name:" + httpsessionbindingevent.getName());

}

public void valueUnbound(HttpSessionBindingEvent httpsessionbindingevent) {

System.out.println("valueUnbound Name:" + httpsessionbindingevent.getName());

}

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

} //钝化    public void sessionWillPassivate(HttpSessionEvent httpsessionevent) {        System.out.println("sessionWillPassivate "+httpsessionevent.getSource());    }    //活化    public void sessionDidActivate(HttpSessionEvent httpsessionevent) {        System.out.println("sessionDidActivate "+httpsessionevent.getSource());    } }

init.jsp <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";request.getSession().setAttribute("currentUser", new com.forezp.entity.User()); %> < !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > < html > < head > < base href = "<%=basePath%>" > < title > My JSP 'init.jsp'

starting page < /title>    <meta http-equiv="pragma" content="no-cache">    <meta http-equiv="cache-control" content="no-cache">    <meta http-equiv="expires" content="0">        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">    <meta http-equiv="description" content="This is my page">    <!--    <link rel="stylesheet" type="text/css

" href="

styles.css ">    -->  </head>  <body>    这是初始化值的界面    <button onclick="

location.href = '<%=request.getContextPath()%>/init.jsp';

">Init</button>    <button onclick="

location.href = '<%=request.getContextPath()%>/destory.jsp';

">Destory</button>  </body></html>

destroy.jsp <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";request.getSession().removeAttribute("currentUser"); %> < !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > < html > < head > < base href = "<%=basePath%>" > < title > My JSP 'destory.jsp'

starting page < /title>    <meta http-equiv="pragma" content="no-cache">    <meta http-equiv="cache-control" content="no-cache">    <meta http-equiv="expires" content="0">        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">    <meta http-equiv="description" content="This is my page">    <!--    <link rel="stylesheet" type="text/css

" href="

styles.css ">    -->  </head>  <body>    这是销毁界面    <button onclick="

location.href = '<%=request.getContextPath()%>/init.jsp';

">Init</button>    <button onclick="

location.href = '<%=request.getContextPath()%>/destory.jsp';

">Destory</button>  </body></html>

当访问init.jsp, 再访问destroy.jsp;

再访问init, jsp, 再关闭服务器, 重启; log日志如下:

valueBound Name: currentUser

valueUnbound Name: currentUser

sessionWillPassivate org.apache.catalina.session.StandardSessionFacade @33f3be1

sessionDidActivate

org.apache.catalina.session.StandardSessionFacade @33f3be1

六、 显示在线人数:

@WebListenerpublic class MyHttpSessionListener implements HttpSessionListener {

private int userNumber = 0;

@Override public void sessionCreated(HttpSessionEvent arg0) {

userNumber++;

arg0.getSession().getServletContext().setAttribute("userNumber", userNumber);

}

@Override public void sessionDestroyed(HttpSessionEvent arg0) {

userNumber--;

arg0.getSession().getServletContext().setAttribute("userNumber", userNumber);

}

}

jsp中显示:

< body > 当前在线用户人数: $ {

userNumber

} < br / > < /body>

这是一个简答的统计在线人数的方法, 如果你需要知道这些人来自哪里, 需要配合httpRequestListener配合, 也可以实现单登陆, 在这里不写代码了。



文/ 方志朋( 简书作者)

原文链接: http: //www.jianshu.com/p/f2c4a9ad45d0

著作权归作者所有, 转载请联系作者获得授权, 并标注“ 简书作者”。


如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

¥ 打赏支持
40人赞 举报
分享到
用户评价(0)

暂无评价,你也可以发布评价哦:)

扫码APP

扫描使用APP

扫码使用

扫描使用小程序