慕课网 java web ---监听器

时间:2021-08-24 22:04:31

Web监听器简介、用途:

Web监听器简介

1.由Servlet规范提供的,可以对客户端的请求、服务端的操作进行监听
2.用于监听ServletContext、HttpSession、ServletRequest等域对象的创建于销毁事件,
分别对应application、session、request对象,
3.用于监听域对象的属性发生修改的事件
4.可以在事件发生前、发生后做一些必要的处理


application是上下文对象,是由容器创建和初始化的,范围是整个web应用,而且整个web应用只有一个application对象,当web服务器关闭时,就会被销毁。
session是保存上下文信息的机制,是针对每一个会话的,是放在服务器端通过sessionid来区分的。在浏览器和服务器结束后,都会把session销毁。
request对象是当客户发送请求时,容器就会创建一个ServletRequest对象,来进行封装请求处理,同时会创建一个ServletResponse对象来进行封装响应处理,在访问结束请求之后,这个对象就会被销毁。


Web监听器的用途:

1、统计在线人数和在线用户;
2、系统启动时加载初始化信息;
3、统计网站访问量;
4、跟Spring结合;


优先级:

监听器>过滤器>servelt


监听器分类:

1.按监听器的对象划分:

a 用户监听应用程序环境对象(ServletContext)的时间监听器
b 用于监听用户会话对象(HttpSession)的事件监听器
c 用于监听请求消息对象(ServletRequest)的事件监听器。

2.按事件划分

a 监听域对象自身的创建和销毁的事件监听器
b 监听域对象中的属性的增加和删除的事件监听器
c 监听绑定到HttpSession域中的某个对象的状态的事件监听器


ServletContext的创建和销毁:

实现ServletContextListener接口
一个项目中可以有多个ServletContextListener,但是只有一个ServletContext对象
主要用途:定时器,全局属性对象
监听器小案例
1.创建类FirstListener  实现ServletContextListener接口
2.配置web.xml--->listeners params
 <context-param>
  <param-name>initparm</param-name>
  <param-value>imooc</param-value>
 </context-param>
 <listener>
  <listener-class>FirstListener</listener-class>
 </listener>
3.重写函数contextInitialized()、contextDestroyed()
  获取ServletContext对象:ServletContext sc = arg0.getServletContext();
  获取初始化参数:String initparm= sc.getInitParameter("initparm");
  可以往ServletContext里放一些值进去sc.setAttribute("name", "user");
System.out.println("contextDestroyed"+initparm+sc.getAttribute("name"));


HttpSession的创建和销毁:

实现HttpSessionListener接口
一个HttpSession可以注册多个HttpSessionListener接口,
一个web应用中可以有多个HttpSession对象
主要用途:统计在线人数,记录访问日志
<session-config>
<!-- 设定超时销毁时间(分钟) 然而这个时间并不精确,而且当为0的时候表示无超时销毁-->
<session-timeout>1</session-timeout>
</session-config>


ServletRequest的事件监听器:

实现ServletRequestListener接口
一个ServletRequest可以注册多个ServletRequestListener接口
主要用途:读取参数,记录访问历史
request监听的是用户的每一个访问请求
获取ServletRequest对象: ServletRequest sr = sre.getServletRequest();
获取初始化参数:sr.getInitParmeter("initparm");


属性的增加和删除的事件监听器

ServletContext、HttpSession、ServletRequest对象的中属性的增加和删除有单独的事件监听器
XXAttributeListner

监听的事件包括
attributeAdded()
attributeRemoved()
attributeReplaced()

区别:
request.getAttribute的值获得是从request.setAttribute的值
request.getParameter是请求的参数值
init.jsp
request.setAttribute("name","name");
request.getSession().setAttribute("name","name");
request.getSession().getServletContext().setAttribute("name","name");
destroy.jsp
request.removeAttribute("name");
request.getSession().removeAttribute("name");
request.getSession().getServletContext().removeAttribute("name");


监听绑定到httpsession的某个对象的状态的事件监听器

1,绑定到Session中的 对象有多种状态,分别是   绑定   解除绑定     钝化    活化。
绑定 是保存,通过session.setattribute把对象保存到session的对象当中,解除绑定,remove。钝化就是将session持久化存储设备上。活化就是将session对象从一个存储设备上进行恢复。
2,session的钝化机制:
session正常是放到服务器内存当中的,当在线用户很多时,session内存的开销是巨大的,会直接影响web服务器的性能,session的钝化机制就会解决这个问题
session钝化的本质就是把服务器不经常使用的session对象暂时序列化到系统文件,整个的过程是由服务器自动完成的
3,Tomcat中两种Session钝化管理器
   session钝化机制是由sessionManager管理
1)StandarManager
        org.apache.catalina.session.StandarManager
         当Tomcat服务器关闭或者重启时tomcat服务器会将当前内存中的session对象钝化到服务器文件系统中;
          另一种情况是web应用程序被重新加载时,内存中的session对象也会被钝化到服务器的文件系统中
2)Persistentmanager
   org.apache.catalina.session.Persistentmanager
      首先在钝化的基础上进行扩张,第一种情况如上面1,第2种如2,第3种情况,可以配置主流内存的session对象数目,将不长使用的session对象保存到系统文件或数据库,当用时再重新加载
      默认情况下,Tomcat提供2个钝化驱动类
4,servlet规范:
   接口:HttpServletBindingListener
         HttpSessionActionListener
5,实例部分:
当对象实现Persistentmanager的接口之后,这个对象被session绑定了,这时会触发事件,执行方法


servlet3.0下监听器的使用

1,使用3.0的前提条件:
     1)使用servlet3.0新标准jar包
      2)JDK必须在1.6以上版本
       3)编译器的编译级别为6.0
         4)在web.xml文件中,使用3.0规范
         5)使用支持servlet3.0特性的web容器,比如tomcat7,6是不行的
2,监听器的用法:


只需加入注解就可以了,该注解用于将类声明为监听器,被@webListener标注的类必须实现以下至少一个接口:
ServletContextListener
ServletContextAttributeListener
ServletRequestListener
ServletRequestAttributeListener
HttpSessionListener
HttpSessionAttributeListener


3,@WebListener的常用属性
<listener>
       <listener-class>footmark.servlet.SimpleListener</listener-class>
</listener>


@@WebListener("this is only a demo listener")
public class SimpleListener implements ServletContextListener{...}


项目案例:统计在线人数

entity.User.java  

package entity;
public class User {
private String sessionIdString;
private String ipString;
private String firstTimeString; //第一次创建时间

public String getSessionIdString() {
return sessionIdString;
}
public void setSessionIdString(String sessionIdString) {
this.sessionIdString = sessionIdString;
}
public String getIpString() {
return ipString;
}
public void setIpString(String ipString) {
this.ipString = ipString;
}
public String getFirstTimeString() {
return firstTimeString;
}
public void setFirstTimeString(String firstTimeString) {
this.firstTimeString = firstTimeString;
}
}



listener.MyHttpSessionListener.java    HttpSessionListener

package listener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.SimpleFormatter;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import util.SessionUtil;

import entity.User;

public class MyHttpSessionListener implements HttpSessionListener {
private int userNumber = 0; //在线人数
public void sessionCreated(HttpSessionEvent arg0) {
userNumber ++;
arg0.getSession().getServletContext().setAttribute("userNumber",userNumber);
}

public void sessionDestroyed(HttpSessionEvent arg0) {
userNumber --;
arg0.getSession().getServletContext().setAttribute("userNumber",userNumber);

ArrayList<User> utils=(ArrayList<User>) arg0.getSession().getServletContext().getAttribute("userNumber");
if(SessionUtil.getUserBySessionId(utils, arg0.getSession().getId())!=null)
{
utils.remove(SessionUtil.getUserBySessionId(utils, arg0.getSession().getId()));
}
}
}



listener.MyServletRequestListenerjava  ServletRequestListener

package listener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
import util.SessionUtil;
import entity.User;
public class MyServletRequestListener implements ServletRequestListener{
private ArrayList<User> userList;//在线用户List
public void requestDestroyed(ServletRequestEvent sre) {
}

public void requestInitialized(ServletRequestEvent sre) {
userList = (ArrayList<User>)sre.getServletContext().getAttribute("userList");

if(userList==null)
userList = new ArrayList<User>();

HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
String sessionIdString = request.getSession().getId();

if(SessionUtil.getUserBySessionId(userList,sessionIdString)==null){
User user = new User();
user.setSessionIdString(sessionIdString);
user.setFirstTimeString(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
user.setIpString(request.getRemoteAddr());
userList.add(user);
}
sre.getServletContext().setAttribute("userList", userList);
}
}


util.SessionUtil.java

package util;
import java.util.ArrayList;
import entity.User;
public class SessionUtil {
public static Object getUserBySessionId(ArrayList<User> userList, String sessionIdString) {
for (int i = 0; i < userList.size(); i++) {
User user = userList.get(i);
if (user.getSessionIdString().equals(sessionIdString)) {
return user;
}
}
return null;
}
}



index.jsp

  
<body>
当前在线用户人数:${userNumber }<br/>
<%
ArrayList<entity.User> userList = (ArrayList<entity.User>)request.getServletContext().getAttribute("userList");
if(userList!=null){
for(int i = 0 ; i < userList.size() ; i++){
com.imooc.entity.User user = userList.get(i);
%>
IP:<%=user.getIpString() %>,FirstTime:<%=user.getFirstTimeString() %>,SessionId:<%=user.getSessionIdString() %> <br/>
<%}} %>
</body>


web.xml   两个监听器

<listener>
  <listener-class>listener.MyHttpSessionListener</listener-class>
 </listener>
 <listener>
  <listener-class>MyServletRequestListener</listener-class>
 </listener>

问题:

1.getServletContext() is undefined for the type HttpServletRequest

      必须是tomcat7.0,否则会出现这个错误

2.未解决

User.java
public class User implements HttpSessionBindingListener ,HttpSessionActivationListener,Serializable{
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println("sessionDidActivate "+se.getSource());
}


public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println("sessionWillPassivate "+se.getSource());
}

public void valueBound(HttpSessionBindingEvent arg0) {
System.out.println("valueBound"+arg0.getName());
}

public void valueUnbound(HttpSessionBindingEvent arg0) {
System.out.println("valueUnbound"+arg0.getName());
}
}


index.jsp
<%request.getSession().setAttribute("currentname",new User());
%>


为何关闭或重启服务器还是没有sessionWillPassivate和sessionDidActivate还是没有执行?