讲给Android程序员看的前端系列教程(40集免费视频教程+源码)
版权声明
- 本文原创作者:谷哥的小弟
- 作者博客地址:http://blog.csdn.net/lfdfhl
Listener概述
Listener也称之为监听器,它是JavaWeb三大组件(Servlet、Filter、Listener)之一。JavaWeb开发中我们有时需要监听域对象HttpServletRequest、HttpSession、ServletContext的创建与销毁及其属性变化;在此,将其分类概述如下:
-
1、监听域对象创建和销毁的事件监听器
例如:ServletContextListener接口、 HttpSessionListener 接口、ServletRequestListener 接口 -
2、监听域对象属性增加和删除的事件监听器
例如:ServletContextAttributeListener 接口、HttpSessionAttributeListener 接口、ServletRequestAttributeListener 接口 -
3、监听绑定在HttpSession中的对象的状态的事件监听器
例如:HttpSessionBindingListener 接口、HttpSessionActivationListener 接口
在Servlet规范中,这三类事件监听器都定义了相应的接口,在编写事件监听器程序时 只需实现对应的接口即可。Web服务器会根据监听器所实现的接口将其注册到被监听的对象上;当触发了某个对象的监听事件时,Web容器将会调用监听器与之相关的方法对事件进行处理。
接下来,我们分别介绍这三类常用的监听器。
监听域对象创建和销毁的事件监听器
在Web应用程序的运行期间,Web容器会创建和销毁三个很重要的对象:ServletContext、HttpSession和ServletRequest,这些对象常被称为域对象。为了监听这些域对象的生命周期,Servlet API 中专门提供三个接口ServletContextListener、HttpSessionListener、 ServletRequestListener,分别用于监听ServletContext对象的生命周期、监听HttpSession 对象的生命周期、监听ServletRequest对象的生命周期。
ServletContextListener接口
该接口常用方法及其作用概述如下:
public void contextInitialized(ServletContextEvent sce)
当ServletContext对象被创建时,Web容器会调用该方法。
public void contextDestroyed(ServletContextEvent sce)
当ServletContext对象被销毁时,Web容器会调用该方法。
HttpSessionListener接口
该接口常用方法及其作用概述如下:
public void sessionCreated(HttpSessionEvent se)
当HttpSession对象被创建时,Web容器会调用该方法。
public void sessionDestroyed(HttpSessionEvent se)
当HttpSession对象被销毁时,Web容器会调用该方法。
ServletRequestListener接口
该接口常用方法及其作用概述如下:
public void requestInitialized(ServletRequestEvent sre)
当ServletRequest对象被创建时,Web容器会调用该方法。
public void requestDestroyed(ServletRequestEvent sre)
当ServletRequest对象被销毁时,Web容器会调用该方法。
监听域对象属性增加和删除的事件监听器
ServletContext对象、HttpSession对象和ServletRequest对象都可创建、删除和修改各自的属性。为了监听对象的属性变更,Servlet API专门提供了,ServletContextAttributeListener、HttpSessionAttributeListener 和ServletRequestAttributeListener
接口,分别用于监听ServletContext对象中的属性变更,监听HttpSession对象中的属性变更,监听ServletRequest对象中的属性变更。
ServletContextAttributeListener接口
该接口常用方法及其作用概述如下:
public void attributeAdded(ServletContextAttributeEvent event)
当向ServletContext对象中添加属性时,Web容器会调用该方法。
public void attributeRemoved(ServletContextAttributeEvent event)
当从ServletContext对象中删除属性时,Web容器会调用该方法。
public void attributeReplaced(ServletContextAttributeEvent event)
当替换ServletContext对象中的属性时,Web容器会调用该方法。
HttpSessionAttributeListener 接口
该接口常用方法及其作用概述如下:
public void attributeAdded(HttpSessionBindingEvent event)
当向HttpSession对象中添加属性时,Web容器会调用该方法。
public void attributeRemoved(HttpSessionBindingEvent event)
当从HttpSession对象中删除属性时,Web容器会调用该方法。
public void attributeReplaced(HttpSessionBindingEvent event)
当替换HttpSession对象中的属性时,Web容器会调用该方法。
ServletRequestAttributeListener接口
该接口常用方法及其作用概述如下:
public void attributeAdded(ServletRequestAttributeEvent event)
当向ServletRequest对象中添加属性时,Web容器会调用该方法。
public void attributeRemoved(ServletRequestAttributeEvent event)
当从ServletRequest对象中删除属性时,Web容器会调用该方法。
public void attributeReplaced(ServletRequestAttributeEvent event)
当替换ServletRequest对象中的属性时,Web容器会调用该方法。
监听绑定在HttpSession中的对象的状态的事件监听器
在JavaWeb程序开发中经常使用Session域存储对象,每个对象在该域中都有多种状态。例如:绑定(保存)到Session域中、从Session域中解除绑定、对象随Session持久化到一个存储设备中 (钝化)、对象随Session从存储设备中恢复(活化)。为观察Session域中对象的状态,Servlet API还提供了两个特殊的监听器接口HttpSessionBindingListener和 HttpSessionActivationListener。
HttpSessionBindingListener接口
该接口常用方法及其作用概述如下:
public void valueBound(HttpSessionBindingEvent event)
当对象被绑定到HttpSession中,Web容器会调用该方法。
public void valueUnbound(HttpSessionBindingEvent event)
当对象从HttpSession中解绑时,Web容器会调用该方法。
HttpSessionActivationListener接口
该接口常用方法及其作用概述如下:
public void sessionWillPassivate(HttpSessionEvent se)
当对象随着HttpSession被钝化时,Web容器会调用该方法。
public void sessionDidActivate(HttpSessionEvent se)
当对象随着HttpSession被活化时,Web容器会调用该方法。
Listener应用示例
在此,以示例形式介绍Listener常用应用场景及其使用方式。
功能描述
统计网站当前在线人数。
思路分析
- 客户端浏览器通知服务端创建HttpSession
- 服务端利用HttpSessionListener感知HttpSession的创建与销毁
测试方式
使用Chrome、IE、Eclipse内置浏览器分别访问该Web应用即可观察测试结果。
index.html
<!DOCTYPE html>
<!-- 本文作者:谷哥的小弟-->
<!-- 博客地址:https://blog.csdn.net/lfdfhl-->
<html>
<head>
<meta charset="utf-8">
<title>index</title>
</head>
<body>
<h2 align="left" style="color: red;">本文作者:谷哥的小弟</h2>
<h2 align="left" style="color: red;">博客地址:http://blog.csdn.net/lfdfhl</h2>
<a href="/Listener05/OnLineCountServlet">查看网站在线人数</a>
</body>
</html>
OnLineCountListener
package cn.com;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*
* HttpSessionListener使用示例
* 统计当前在线人数
*
*/
public class OnLineCountListener implements HttpSessionListener {
private int count=0;
//当HttpSession创建时该方法被调用
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
count++;
HttpSession session = httpSessionEvent.getSession();
//将数据保存至ServletContext
ServletContext context = session.getServletContext();
context.setAttribute("onLineCount", new Integer(count));
}
//当HttpSession销毁时该方法被调用
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
count--;
HttpSession session = httpSessionEvent.getSession();
//更新数据至ServletContext
ServletContext context = session.getServletContext();
context.setAttribute("onLineCount", new Integer(count));
}
}
OnLineCountServlet
package cn.com;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class OnLineCountServlet extends HttpServlet {
private static final long serialVersionUID = -1294904754142676214L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter writer = response.getWriter();
writer.write("<!DOCTYPE html>");
writer.write("<html>");
writer.write("<head>");
writer.write("<meta charset=\"UTF-8\">");
writer.write("<title>Servlet</title>");
writer.write("</head>");
writer.write("<body>");
//获取HttpSession,服务端若有则返回;服务端若无则创建
//触发HttpSessionListener的sessionCreated()
request.getSession();
//从ServletContext获取数据
ServletContext servletContext = getServletContext();
Object onLineCount = servletContext.getAttribute("onLineCount");
writer.write("<H1>onLineCount="+onLineCount+"</H1>");
writer.write("<a href="+"\""+"/Listener05/"+"LogoutServlet"+"\""+">Logout</a>");
writer.write("</body>");
writer.write("</html>");
}
}
LogoutServlet
package cn.com;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class LogoutServlet extends HttpServlet {
private static final long serialVersionUID = 701606097105591063L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter writer = response.getWriter();
writer.write("<!DOCTYPE html>");
writer.write("<html>");
writer.write("<head>");
writer.write("<meta charset=\"UTF-8\">");
writer.write("<title>Servlet</title>");
writer.write("</head>");
writer.write("<body>");
HttpSession session = request.getSession();
//使HttpSession失效
//触发HttpSessionListener的sessionDestroyed()
session.invalidate();
//从ServletContext获取数据
ServletContext servletContext = getServletContext();
Object onLineCount = servletContext.getAttribute("onLineCount");
writer.write("<H1>onLineCount="+onLineCount+"</H1>");
writer.write("</body>");
writer.write("</html>");
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>Listener05</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 配置监听器 -->
<listener>
<listener-class>cn.com.OnLineCountListener</listener-class>
</listener>
<!-- 配置Servlet -->
<servlet>
<servlet-name>OnLineCountServlet</servlet-name>
<servlet-class>cn.com.OnLineCountServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>OnLineCountServlet</servlet-name>
<url-pattern>/OnLineCountServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>LogoutServlet</servlet-name>
<servlet-class>cn.com.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LogoutServlet</servlet-name>
<url-pattern>/LogoutServlet</url-pattern>
</servlet-mapping>
</web-app>
转载:https://blog.csdn.net/lfdfhl/article/details/102014996