`
yangshen998
  • 浏览: 1240521 次
文章分类
社区版块
存档分类
最新评论

监听器(实现在线统计人数,踢人)

 
阅读更多


Servlet监听器

一、监听三个域对象创建和销毁的事件监听器

1. ServletContextListener接口

MyServletContextListener

public class MyServletContextListener implements ServletContextListener {

public void contextDestroyed(ServletContextEvent arg0) {

System.out.println(arg0.getServletContext() + "被创建了");

}

public void contextInitialized(ServletContextEvent arg0) {

System.out.println(arg0.getServletContext() + "被销毁了");

}

}

Web.xml

<listener> <listener-class>cn.class3g.web.listener.MyServletContextListener

</listener-class>

</listener>

应用:在web服务的启动时提供或创建资源,结束时回收。如web应用启动时利用ServletContextListener将数据表和数据准备好,则将创建表和数据的代码写在其中。Spring框架就是以监听器的形式启动的。

问:如果有多个监听器,在web.xml中注册时,怎样判断监听器的监听对象的?

答:利用java的反射机制

If(Object instanceOf ServletContextListener){

}else if( Object instanceOf HttpSessionListener){

}

2. HttpSessionListener接口

MySessionListener

public class MyHttpSessionListener implements HttpSessionListener {

public void sessionCreated(HttpSessionEvent arg0) {

System.out.println(arg0.getSource() + "被销毁了");

}

public void sessionDestroyed(HttpSessionEvent arg0) {

System.out.println(arg0.getSource() + "被创建了");

}

}

注册这个监听器

问:这两句打印什么时候会输出?

直接访问index.jsp或index.html会不会输出

引申出:session对象何时被创建???

答:访问index.html时不会创建session,但是jsp文件被访问是会创建session,因为session对象在getSession()方法被调用是才会创建,而jsp文件被译成servlet时java代码中有此方法的调用

_jspx_page_context = pageContext;

application = pageContext.getServletContext();

config = pageContext.getServletConfig();

session = pageContext.getSession();

。。。

如jsp页面中的page命令如下

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

则servlet中不会调用getSession()

刷新jsp页面会不会打印

开心的浏览器访问jsp会不会打印

浏览器被关闭会不会摧毁session??不会,因为session默认存在30分钟

HttpSessionListener的作用:统计在线人数

3. ServletRequestListener接口

MyServletRequestListener

public class MyServletRequestListener implements ServletRequestListener {

public void requestDestroyed(ServletRequestEvent arg0) {

System.out.println("请求对象"+arg0.getSource() + "被销毁了");

}

public void requestInitialized(ServletRequestEvent arg0) {

System.out.println("请求对象"+arg0.getSource() + "被创建了");

}

}

ServletRequestListener的实际用途:统计网站的请求数量,可以计算网站性能(实际应用不多)

案例:统计当前在线人数

OnlineListener

public class OnlineListener implements HttpSessionListener {

public void sessionCreated(HttpSessionEvent arg0) {

ServletContext context = arg0.getSession().getServletContext();

Integer count = (Integer) context.getAttribute("peopleOnline");

if (count == null) {

count = 1;

} else {

count++;

}

context.setAttribute("peopleOnline", count);

}

public void sessionDestroyed(HttpSessionEvent arg0) {

ServletContext context = arg0.getSession().getServletContext();

Integer count = (Integer) context.getAttribute("peopleOnline");

count--;

context.setAttribute("peopleOnline", count);

}

}

web.xml

<listener>

<listener-class>cn.class3g.web.listener.OnlineListener

</listener-class>

</listener>

Index.jsp

<body>

当前在线人数为:${applicationScope.peopleOnline }

<%

System.out.println(application.getAttribute("peopleOnline"));

%>

</body>


二、监听三个域对象属性变化

1. ServletContextAttributeListener接口

MyServletContextAttributeListener

public class MyServletContextAttributeListener implements

ServletContextAttributeListener {

public void attributeAdded(ServletContextAttributeEvent arg0) {

ServletContext context = arg0.getServletContext();

Object data = arg0.getValue();

System.out.println(context + "中加入了"+data);

}

public void attributeRemoved(ServletContextAttributeEvent arg0) {

ServletContext context = arg0.getServletContext();

Object data = arg0.getValue();

System.out.println(context + "中删除了"+data);

}

public void attributeReplaced(ServletContextAttributeEvent arg0) {

ServletContext context = arg0.getServletContext();

Object data = arg0.getValue();

System.out.println(context + "中更新了"+data);

}

}

Index.jsp

<%

application.setAttribute("param","xxx");

application.setAttribute("param","yyy");

application.removeAttribute("param");

%>

ServletContextAttributeEvent .getValue

public java.lang.Object getValue()

Returns the value of the attribute that has been added removed or replaced. If the attribute was added, this is the value of the attribute. If the attrubute was removed, this is the value of the removed attribute. If the attribute was replaced, this is the old value of the attribute.

2. HttpSessionAttributeListener接口

3. ServletRequestAttributeListener接口

MyHttpSessionAndRequestAttributeListener

public class MyHttpSessionAndRequestAttributeListener implements

HttpSessionAttributeListener, ServletRequestAttributeListener {

public void attributeAdded(HttpSessionBindingEvent se) {

System.out.println("session中增加了属性");

}

public void attributeRemoved(HttpSessionBindingEvent se) {

System.out.println("session中删除了属性");

}

public void attributeReplaced(HttpSessionBindingEvent se) {

System.out.println("session中属性被替换了");

}

public void attributeAdded(ServletRequestAttributeEvent srae) {

System.out.println("request中增加了属性");

}

public void attributeRemoved(ServletRequestAttributeEvent srae) {

System.out.println("request中删除了属性");

}

public void attributeReplaced(ServletRequestAttributeEvent srae) {

System.out.println("request中属性被替换了");

}

}

Index.jsp

<%

session.setAttribute("param","aaa");

session.setAttribute("param","bbb");

session.removeAttribute("param");

request.setAttribute("param","aaa");

request.setAttribute("param","bbb");

request.removeAttribute("param");

%>


三、感知 Session 绑定的事件监听器

保存在 Session 域中的对象可以有多种状态:

绑定到 Session 中;从 Session 域中解除绑定;

随 Session 对象持久化到一个存储设备中;

随 Session 对象从一个存储设备中恢复

Servlet 规范中定义了两个特殊的监听器接口来帮助 JavaBean 对象了解自己在 Session 域中的这些状态:HttpSessionBindingListener接口和HttpSessionActivationListener接口 ,实现这两个接口的类不需要 web.xml 文件中进行注册

监听自己——>不需要注册

事件源是自己

1. HttpSessionBindingListener接口

实现了HttpSessionBindingListener接口的 JavaBean 对象可以感知自己被绑定到 Session 中和从 Session 中删除的事件

cn.class3g.domain.User

public class User implements HttpSessionBindingListener{

private String name;

public void valueBound(HttpSessionBindingEvent event) {

System.out.println("到session中去");

}

public void valueUnbound(HttpSessionBindingEvent event) {

System.out.println("从session中移除");

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

Index.jsp

<%

session.setAttribute("user",new User());

session.removeAttribute("param");

%>

实际用途:

统计网站在线用户(和在线人数不同),当前网站在线用户(作业)

2. HttpSessionActivationListener接口

实现了HttpSessionActivationListener接口的 JavaBean 对象可以感知自己被活化和钝化的事件

什么是钝化、活化

cn.class3g.domain.Person

public class Person implements HttpSessionActivationListener, Serializable {

public void sessionDidActivate(HttpSessionEvent arg0) {

System.out.println("session从硬盘读入内存了");

}

public void sessionWillPassivate(HttpSessionEvent arg0) {

System.out.println("session被存到硬盘中去了");

}

}

Index.jsp

<%

session.setAttribute("person",new Person());

%>

/META-INF/context.xml

<Context>

<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">

<Store className="org.apache.catalina.session.FileStore" directory="class3g"/>

</Manager>

</Context>

启动服务访问index.jsp页面,等待一分钟,查看后台打印

然后刷新页面,查看打印

重复以上动作,观察活化、钝化过程

到服务器对应目录中查看钝化后的session文件

D:\apache-tomcat-6.0.32\work\Catalina\localhost\Listener_Test\class3g


四、显示登陆用户列表,并实现踢人功能

用户:login.jsp à loginServlet à index.jsp

管理员: listUser.jsp à kickUserServlet

监听器:SessionAttributeListener

Bean: User

cn.class.domain.User

package cn.class3g.domain;

public class User {

private String username;

private String password;

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;

}

}

login.jsp

<form method="post" action="${pageContext.request.contextPath }/servlet/LoginServlet">

用户名:<input type="text" name="username" /><br/>

密码: <input type="password" name="password" /><br/>

<input type="submit" value="登陆" /><br/>

</form>

cn.class.web.servlet.loginServlet.java

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

String username = request.getParameter("username");

String password = request.getParameter("password");

User user = new User();

user.setUsername(username);

user.setPassword(password);

request.getSession().setAttribute("user", user);

response.sendRedirect(request.getContextPath()+"/index.jsp");

}

index.jsp

欢迎您:${user.username }

cn.class.web.listener.SessionAttributeListener

//监听session中user对象的加入

public class SessionAttributeListener implements HttpSessionAttributeListener {

public void attributeAdded(HttpSessionBindingEvent arg0) {

Object obj = arg0.getValue();

if(obj instanceof User){

HttpSession session = arg0.getSession();

Map map = (Map) session.getServletContext().getAttribute("map");

if(map == null){

map = new HashMap();

session.getServletContext().setAttribute("map", map);

}

User user = (User) obj;

map.put(user.getUsername(), session);

}

}

public void attributeRemoved(HttpSessionBindingEvent arg0) {}

public void attributeReplaced(HttpSessionBindingEvent arg0) {}

}

listUser.jsp

当前登陆用户有:<br/>

<c:forEach var="me" items="${map }" >

${me.key } <a href="${pageContext.request.contextPath }

/servlet/kickUserServlet?username=${me.key}" >踢死你</a>

</c:forEach>

cn.class.web.servlet.kickUserServlet.java

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

String username = request.getParameter("username");

Map map = (Map) this.getServletContext().getAttribute("map");

HttpSession session = (HttpSession) map.get(username);

if(session != null){

session.invalidate();

map.remove(username);

}

request.getRequestDispatcher("/listUser.jsp").

forward(request, response);

}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics