现在的位置: 首页 > 综合 > 正文

Servlet事件监听器

2017年12月14日 ⁄ 综合 ⁄ 共 13771字 ⁄ 字号 评论关闭

1、监听器

监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。

2、Servlet监听器

1Servlet规范中定义了多种类型的监听器,它们用于监听的事件源分别为 ServletContext, HttpSession 和 ServletRequest 这三个域对象。

2Servlet规范针对这三个对象上的操作,又把这多种类型的监听器划分为三种类型。

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

监听域对象中属性的增加和删除的事件监听器

监听绑定到 HttpSession 域中的某个对象的状态的事件监听器。(查看API文档)

3、监听servletContext域对象创建和销毁

1ServletContextListener 接口用于监听 ServletContext 对象的创建和销毁事件。

2当 ServletContext 对象被创建时,激发contextInitialized (ServletContextEvent sce)方法

3当 ServletContext 对象被销毁时,激发contextDestroyed(ServletContextEvent sce)方法。

4提问,servletContext域对象何时创建和销毁:

创建:服务器启动针对每一个web应用创建servletcontext

销毁:服务器关闭前先关闭代表每一个web应用的servletContext

4编写 Servlet 监听器

1和编写其它事件监听器一样,编写servlet监听器也需要实现一个特定的接口,并针对相应动作覆盖接口中的相应方法。

2和其它事件监听器略有不同的是,servlet监听器的注册不是直接注册在事件源上,而是由WEB容器负责注册,开发人员只需在web.xml文件中使用<listener>标签配置好监听器,web容器就会自动把监听器注册到事件源中。

3一个 web.xml 文件中可以配置多个 Servlet 事件监听器,web 服务器按照它们在 web.xml 文件中的注册顺序来加载和注册这些 Serlvet 事件监听器。

5、servletContext主流应用

1保存全局应用数据对象

例如:创建数据库连接池

2加载框架配置文件

Spring框架(配置文件随服务器启动加载) org.springframework.web.context.ContextLoaderListener 

3实现任务调度(定时器)

Timer

TimerTask

package com.itheima.listener;

import java.util.HashMap;

import javax.servlet.ServletContextEvent;

import javax.servlet.ServletContextListener;

import javax.servlet.http.HttpSession;

import com.itheima.domain.User;

public class ContextListener implements ServletContextListener {

public void contextDestroyed(ServletContextEvent sce) {

}

public void contextInitialized(ServletContextEvent sce) {

sce.getServletContext().setAttribute("map", new HashMap<User, HttpSession>());

}

}

6监听HttpSession域对象创建和销毁

1HttpSessionListener接口用于监听HttpSession的创建和销毁

2创建一个Session时,sessionCreated(HttpSessionEvent se) 方法将会被调用。

3销毁一个Session时,sessionDestroyed (HttpSessionEvent se) 方法将会被调用。

4(此处复习session对象,写多个servlet都去getSession,看session的创建)

5Session域对象创建和销毁的时机创建:用户每一次访问时,服务器创建session

销毁:如果用户的session 30分钟没有使用,服务器就会销毁session,我们在web.xml里面也可以配置session失效时间

6tomcat/conf/server.xml 添加

<Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="false">

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

</Manager>

tomcat关闭时 不保存session内容

7监听HttpRequest域对象创建和销毁

1ServletRequestListener 接口用于监听ServletRequest 对象的创建和销毁。

(2)Request 对象被创建时,监听器的requestInitialized方法将会被调用。

(3)Request对象被销毁时,监听器的requestDestroyed方法将会被调用。

(4)(此处复习request对象,在浏览器窗口中多次刷新访问servlet,看request对象的创建和销毁,并写一个servlet,然后用sendRedirectforward方式跳转到其它servlet,查看request对象的创建和消耗)

(5)servletRequest域对象创建和销毁的时机:

创建:用户每一次访问,都会创建一个reqeust

销毁:当前访问结束,request对象就会销毁

8Servlet监听器在开发中的应用案例:

1统计当前在线人数 

2*自定义session定时扫描器(销毁session对象)

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

1Servlet规范定义了监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信息事件的监听器。

2这三个监听器接口分别是ServletContextAttributeListener, HttpSessionAttributeListener ServletRequestAttributeListener

3这三个接口中都定义了三个方法来处理被监听对象中的属性的增加,删除和替换的事件,同一个事件在这三个接口中对应的方法名称完全相同,只是接受的参数类型不同。 

package com.itheima.listener;

import javax.servlet.ServletContextAttributeEvent;

import javax.servlet.ServletContextAttributeListener;

public class MyServletContextAttributeListener implements

ServletContextAttributeListener {

public void attributeAdded(ServletContextAttributeEvent scab) {

System.out.println("属性被增加进ServletContext域了"+scab.getName()+":"+scab.getValue());

}

public void attributeRemoved(ServletContextAttributeEvent scab) {

System.out.println("属性被移除出ServletContext域了"+scab.getName()+":"+scab.getValue());

}

public void attributeReplaced(ServletContextAttributeEvent scab) {

System.out.println("属性被替换从ServletContext域中"+scab.getName()+":"+scab.getValue()+":"+scab.getServletContext().getAttribute(scab.getName()));

}

}

10、attributeAdded 方法

1当向被监听器对象中增加一个属性时,web容器就调用事件监听器的 attributeAdded 方法进行相应,这个方法接受一个事件类型的参数,监听器可以通过这个参数来获得正在增加属性的域对象和被保存到域中的属性对象

2各个域属性监听器中的完整语法定义为:

public void attributeAdded(ServletContextAttributeEvent scae) 

public void attributeAdded (HttpSessionBindingEvent  hsbe) 

public void attributeAdded(ServletRequestAttributeEvent srae)

11attributeRemoved 方法

1当删除被监听对象中的一个属性时,web 容器调用事件监听器的这个方法进行相应

2各个域属性监听器中的完整语法定义为:

public void attributeRemoved(ServletContextAttributeEvent scae) 

public void attributeRemoved (HttpSessionBindingEvent  hsbe) 

public void attributeRemoved (ServletRequestAttributeEvent srae)

12、attributeReplaced 方法

1当监听器的域对象中的某个属性被替换时,web容器调用事件监听器的这个方法进行相应

2各个域属性监听器中的完整语法定义为:

public void attributeReplaced(ServletContextAttributeEvent scae) 

public void attributeReplaced (HttpSessionBindingEvent  hsbe) 

public void attributeReplaced (ServletRequestAttributeEvent srae)

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

1保存在 Session 域中的对象可以有多种状态:绑定到  Session 中;从 Session 域中解除绑定;随 Session 对象持久化到一个存储设备中(钝化);随 Session 对象从一个存储设备中恢复(活化)

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

14、HttpSessionBindingListener接口

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

2当对象被绑定到 HttpSession 对象中时,web 服务器调用该对象的  void valueBound(HttpSessionBindingEvent event) 方法

3当对象从 HttpSession 对象中解除绑定时,web 服务器调用该对象的 void valueUnbound(HttpSessionBindingEvent event)方法

package com.itheima.domain;

import javax.servlet.http.HttpSessionBindingEvent;

import javax.servlet.http.HttpSessionBindingListener;

public class Person implements HttpSessionBindingListener {

private String name;

private int age;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public void valueBound(HttpSessionBindingEvent event) {

System.out.println("Person被绑定到session当中。。。。。");

}

public void valueUnbound(HttpSessionBindingEvent event) {

System.out.println("Person被移除出sesison了。。。。");

}

}

15、HttpSessionActivationListener接口

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

2当绑定到 HttpSession 对象中的对象将要随 HttpSession 对象被钝化之前,web 服务器调用如下方法sessionWillPassivate(HttpSessionBindingEvent event) 方法

3当绑定到 HttpSession 对象中的对象将要随 HttpSession 对象被活化之后,web 服务器调用该对象的 void sessionDidActive(HttpSessionBindingEvent event)方法

package com.itheima.domain;

import java.io.Serializable;

import javax.servlet.http.HttpSessionActivationListener;

import javax.servlet.http.HttpSessionEvent;

public class Teacher implements HttpSessionActivationListener,Serializable {

private String name;

private int age;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public void sessionDidActivate(HttpSessionEvent se) {

System.out.println("Teacher 对象随着session被活化了。。。。");

}

public void sessionWillPassivate(HttpSessionEvent se) {

System.out.println("Teacher 对象随着session被钝化了。。。。");

}

}

1.监听三大作用域创建与销毁的监听器

ServletContextListener:tomcat服务器启动时web应用开始加载,代表web应用的Servletcontext对象被创建,服务器关闭或web应用被移除出容器时销毁

void contextDestroyed(ServletContextEvent sce)  

 void contextInitialized(ServletContextEvent sce)  

HttpSessionListener:第一次调用request.getSession方法时session对象被创建,session超时、服务器非正常关闭、调用自杀的方法。session的钝化和活化。钝化:当服务器正常关闭时,还存活的session将被以文件的形式保存在服务器当中,这个过程叫做session的钝化。活化:文件中的session在服务器正常重启时,将从文件中恢复到内存中来,这个过程叫做sesison的活化。

 void sessionCreated(HttpSessionEvent se) 

 void sessionDestroyed(HttpSessionEvent se)  

ServletRequestListener:当一次请求发生,服务器会创建一个request对象代表请求,一次请求结束,request对象销毁。

void requestDestroyed(ServletRequestEvent sre) 

  void requestInitialized(ServletRequestEvent sre) 

2.监听三大作用中的属性的改变的监听器

ServletContextAttributeListener

HttpSessionAttributeListener 

ServletRequestAttributeListener

 

void attributeAdded(ServletContextAttributeEvent scab) 

          Notification that a new attribute was added to the servlet context. 

void attributeRemoved(ServletContextAttributeEvent scab) 

          Notification that an existing attribute has been removed from the servlet context. 

void attributeReplaced(ServletContextAttributeEvent scab) 

          Notification that an attribute on the servlet context has been replaced. 

3.感知JavaBeansession域中的状态变化的监听器:这两种监听器的接口,需要由被绑定到session当中的JavaBean类去实现,并且不需要在web.xml文件中进行描述。

HttpSessionBindingListener

 void valueBound(HttpSessionBindingEvent event) :被绑定时调用

          Notifies the object that it is being bound to a session and identifies the session. 

 void valueUnbound(HttpSessionBindingEvent event) :被移除绑定时调用

          Notifies the object that it is being unbound from a session and identifies the session. 

HttpSessionActivationListener

 void sessionDidActivate(HttpSessionEvent se) :被活化时调用

          Notification that the session has just been activated. 

 void sessionWillPassivate(HttpSessionEvent se) : 被钝化时调用

          Notification that the session is about to be passivated. 

*一个对象如果想要随着session的钝化而钝化就必须实现一个特定的接口叫做Serializable接口

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

package com.itheima.doamin;

import java.util.Map;

import javax.servlet.http.HttpSession;

import javax.servlet.http.HttpSessionBindingEvent;

import javax.servlet.http.HttpSessionBindingListener;

public class User implements HttpSessionBindingListener {

private int id;

private String username;

private String password;

private String role;

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

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 String getRole() {

return role;

}

public void setRole(String role) {

this.role = role;

}

public void valueBound(HttpSessionBindingEvent event) {

Map<String , HttpSession> map = (Map<String , HttpSession>) event.getSession().getServletContext().getAttribute("userMap");

map.put(username, event.getSession());

}

public void valueUnbound(HttpSessionBindingEvent event) {

Map<String , HttpSession> map = (Map<String , HttpSession>) event.getSession().getServletContext().getAttribute("userMap");

map.remove(username);

}

}

package com.itheima.listener;

import java.util.HashMap;

import javax.servlet.ServletContextEvent;

import javax.servlet.ServletContextListener;

import javax.servlet.http.HttpSession;

public class MyServletContextListener implements ServletContextListener {

public void contextDestroyed(ServletContextEvent sce) {

}

public void contextInitialized(ServletContextEvent sce) {

sce.getServletContext().setAttribute("app", sce.getServletContext().getContextPath());

sce.getServletContext().setAttribute("userMap", new HashMap<String, HttpSession>());

}

package com.itheima.util;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class DaoUtil {

private static  DataSource source = new ComboPooledDataSource();

private DaoUtil() {

}

public static DataSource getSource(){

return source;

}

}

package com.itheima.web;

import java.io.IOException;

import java.util.Map;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

public class KickServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

request.setCharacterEncoding("utf-8");

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

Map<String, HttpSession> map = (Map<String, HttpSession>) this.getServletContext().getAttribute("userMap");

HttpSession session = map.get(username);

if(session!=null){

session.invalidate();

}

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

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request, response);

}

}

package com.itheima.web;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.dbutils.QueryRunner;

import org.apache.commons.dbutils.handlers.BeanHandler;

import com.itheima.doamin.User;

import com.itheima.util.DaoUtil;

public class LoginServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

request.setCharacterEncoding("utf-8");

try{

//1.校验用户名密码是否正确

QueryRunner runner = new QueryRunner(DaoUtil.getSource());

User user = runner.query("select * from user where username=? and password=?", new BeanHandler<User>(User.class),request.getParameter("username"),request.getParameter("password"));

if(user == null){

request.setAttribute("msg", "用户名密码不正确!!");

request.getRequestDispatcher("/login.jsp").forward(request, response);

return;

}else{

//用户名密码都正确,在session域中保存用户的登录状态

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

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

}

}catch (Exception e) {

e.printStackTrace();

}

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request, response);

}

}

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

<%@taglib uri="http://java.sun.com/jsp/jstl/coreprefix="c" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

  </head>

  <body>

   <h1>用户列表</h1>

   <c:if test="${sessionScope.user==null}">

   请先去登录!<a href="${app }/login.jsp">登录</a>

   </c:if>

   <c:if test="${sessionScope.user!=null}">

   <c:forEach items="${userMap}" var="entry">

   ${entry.key }

   <c:if test="${sessionScope.user.role == 'admin'}">

   <a href="${app }/servlet/KickServlet?username=${entry.key }">踢人</a>

   </c:if>

   <br>

   </c:forEach>

   </c:if>

  </body>

</html>

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

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

  </head>

  <body>

  ${msg }

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

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

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

   <input type="submit" value="提交" />

   </form>

  </body>

</html>

【上篇】
【下篇】

抱歉!评论已关闭.