java 学习之路 - web监听器

什么是web监听器

web监听器主要是对Servlet对象进行监听和动作的,它可以监听客户端的请求,服务端的操作等

web监听器的分类

根据监听的域对象可以分为三类
    1.监听Servlet上下文对象的监听器
        1. 对Servlet上下文对象初始化及对象销毁动作进行监听的  ServletContextListener
        2. 对Servlet上下文对象的属性进行监听的 ServletContextAttributeListener
    2.监听HTTP会话 Session对象的监听器
        1. 对HTTP Session对象初始化及销毁动作进行监听的  HttpSessionListener
        2. 对HTTP Session对象的属性进行监听的  HttpSessionAttributeListener
        3. 对HTTP Session对象设置的属性对象进行监听的 HttpSessionBindingListener
        4. 对HTTP Session对象的活跃性进行监听的 HttpSessionActivationListener
    3.监听客户端请求Servlet Request对象的监听器
        1. 对Servlet Request对象初始化及销毁动作进行监听的 ServletRequestListener
        2. 对Servlet Request对象的属性进行监听的 ServletRequestAttributeListener

各监听器的使用Demo

 注:本文使用的是Servlet3.0,所以基于@WebListener注解进行代码演示,如果是其他版本只需在web.xml文件中配置listener即可
1. 监听Servlet上下文对象的 ServletContextListener
    要对Servlet上下文 对象进行监听只需实现ServletContextListener接口即可,此接口只有两个方法,分别为Servlet启动初始化方法contextInitialized(可以对ServletContext做相应的初始化操作),以及Servlet销毁方法contextDestroyed(可以对ServletContext所持有的资源进行释放);在tomcat中通start命令启动时,监听到Servlet对象的创建后contextInitialized方法会被执行,当执行shutdown命令时,监听到Servlet对象将被销毁,contextDestroyed方法会被执行。
@WebListener
public class MyServletContextListener implements ServletContextListener {
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("---------------------------------------------");
        System.out.println("MyServletContextListener contextInitialized");
        System.out.println("---------------------------------------------");
    }

    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("---------------------------------------------");
        System.out.println("MyServletContextListener contextDestroyed");
        System.out.println("---------------------------------------------");
    }
}

2.监听Servlet上下文对象属性变化的 ServletContextAttributeListener
要对Servlet上下文 对象的属性变化进行监听只需实现ServletContextAttributeListener接口即可,此接口只有三个方法,分别为属性新增时的监听方法(attributeAdded),通过ServletContextAttributeEvent 参数可以对ServletContext及新增的属性内容进行操作;已有属性内容被替换时的监听方法(attributeReplaced),此方法在属性被重复赋值(内容替换)时调用,可通过ServletContextAttributeEvent 参数进行操作;当ServletContext的属性被移除时的监听方法(attributeRemoved),通过ServletContextAttributeEvent 参数获取ServletContext属性内容时已是空。
@WebListener
public class MyServletContextAttributeListener implements ServletContextAttributeListener {
    public void attributeAdded(ServletContextAttributeEvent event) {
        System.out.print("MyServletContextAttributeListener attributeAdded : [value=");
        ServletContext servletContext = event.getServletContext();
        Enumeration<String> attributeNames = servletContext.getAttributeNames();
        while (attributeNames.hasMoreElements()) {
            System.out.print(attributeNames.nextElement() + ", ");
        }
        System.out.println("]");
        System.out.println("add ServletContextAttribute and value = " + servletContext.getAttribute("name"));

    }

    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
        ServletContext servletContext = servletContextAttributeEvent.getServletContext();
        System.out.println("MyServletContextAttributeListener attributeRemoved and value = " + servletContext.getAttribute("name"));

    }

    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
        ServletContext servletContext = servletContextAttributeEvent.getServletContext();
        System.out.println("MyServletContextAttributeListener attributeReplaced and value = " + servletContext.getAttribute("name"));
    }
}

JSP代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello ServletContextAttributeListener!</h2>
<p>ServletContext changes</p>
<p>request.getServletContext() setAttribute</p>
<p><b>request.getServletContext().setAttribute("name", "add value");</b></p>
<%
    ServletContext servletContext = request.getServletContext();
    servletContext.setAttribute("name", "add value");
%>
<hr/>
<p>request.getServletContext() replaceAttribute</p>
<p><b>request.getServletContext().setAttribute("name", "replace value");</b></p>
<%
    servletContext.setAttribute("name", "replace value");
%>
<hr/>
<p>request.getServletContext() removeAttribute</p>
<p><b>request.getServletContext().removeAttribute("name");</b></p>
<%
    servletContext.removeAttribute("name");
%>
</body>
</html>

3. 对于HttpSession的创建,销毁以及属性的监听与ServletContext类似,分别对应HttpSessionListener和HttpSessionAttributeListener,它们的接口方法与ServletContext接口方法也是类似,此处不再赘述,另外,对于HttpSession的操作可通过HttpSessionEvent和HttpSessionBindingEvent参数进行获取,贴出代码。
@WebListener
public class MyHttpSessionListener implements HttpSessionListener {
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        System.out.println("MyHttpSessionListener sessionCreated : " + session.getId());
    }

    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        System.out.println("MyHttpSessionListener sessionDestroyed : " + session.getId());
    }
}

@WebListener
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        HttpSession session = httpSessionBindingEvent.getSession();
        System.out.println("MyHttpSessionAttributeListener attributeAdded and id = " + session.getId() + ", value = " + session.getAttribute("name"));
    }

    public void attributeRemoved(HttpSessionBindingEvent event) {
        HttpSession session = event.getSession();
        System.out.println("MyHttpSessionAttributeListener attributeRemoved and id = " + session.getId() + ", value = " + event.getValue());
    }

    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        HttpSession session = httpSessionBindingEvent.getSession();
        System.out.println("MyHttpSessionAttributeListener attributeReplaced and id = " + session.getId() + ", value = " + session.getAttribute("name"));
    }
}

JSP代码:
        注:HttpSessionListener的监听在通过浏览器访问服务时即可动作,所以此处没有加操作代码。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello HttpSessionAttributeListener</h2>
<p>HttpSessionAttribute changes</p>
<p>request.getSession() setAttribute</p>
<p><b>request.getSession().setAttribute("name", "add value");</b></p>
<%
    HttpSession httpSession = request.getSession();
    httpSession.setAttribute("name", "add value");
%>
<hr/>
<p>request.getSession() replaceAttribute</p>
<p><b>request.getSession().setAttribute("name", "replace value");</b></p>
<%
    httpSession.setAttribute("name", "replace value");
%>
<hr/>
<p>request.getSession() removeAttribute</p>
<p><b>request.getSession().removeAttribute("name");</b></p>
<%
    httpSession.removeAttribute("name");
%>
<hr/>
</body>
</html>

4. HttpSessionBindingListener用于监听其实现类本身,当实现类对象被添加到session中时(session.setAttribute()),会调用valueBound方法,参数HttpSessionBindingEvent中包含session和实体信息,当实现类对象被从session中移除(session.removeAttribute())或者session失效时,会调用valueUnbound方法。另外,此listener的方法在HttpSessionAttributeListener方法之前执行。
public class MyHttpSessionBindingListener implements HttpSessionBindingListener {
    private String name;

    public MyHttpSessionBindingListener(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "MyHttpSessionBindingListener{" +
                "name=‘" + name + ‘\‘‘ +
                ‘}‘;
    }

    //被设置到session中(setAttribute)
    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        HttpSession session = event.getSession();
        System.out.println("HttpSessionBindingListener bean被设置到session中,sessionId=" + session.getId() + ", bean: " + event.getValue());
    }

    //从session中解除(removeAttribute)
    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        HttpSession session = event.getSession();
        System.out.println("HttpSessionBindingListener bean在session中被移除,sessionId=" + session.getId() + ", bean: " + event.getValue());
    }
}

JSP代码:
<%@ page import="MyHttpSessionBindingListener" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello HttpSessionBindingListener</h2>
<p>HttpSessionBinding changes</p>
<p>session setAttribute</p>
<%
    Object name = session.getAttribute("name");
    if (name == null) {
        MyHttpSessionBindingListener bindingListener = new MyHttpSessionBindingListener("SessionBean");
        session.setAttribute("name", bindingListener);
%>
<p><b>session.setAttribute("name", "new MyHttpSessionBindingListener("SessionBean")");</b></p>
<%} else {%>
<p><b>session.getAttribute("name") : <%= name%>
</b></p>
<%}%>
<hr/>
<p>request.getSession() removeAttribute</p>
<p><b>request.getSession().removeAttribute("name");</b></p>
<%
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    session.removeAttribute("name");
%>
<hr/>
</body>
</html>

5. Session的持久化操作:对于Tomcat服务器来说,可以通过配置context.xml文件来启用此功能(Tomcat中默认没有启用此功能),在Session即将超时时生成sessionId.session文件,配置如下:
    注:当Session在系统中过期时,则Session信息会被清除,同时sessionId.session文件也会被删除
            <Context>
                    <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
                            <Store className="org.apache.catalina.session.FileStore" directory="H:\selfwork\"></Store>
                    </Manager>
            </Context>
            * maxIdleSwap-session处于不活动状态长时间(s),sesson对象转移到FileStore中;(-1表示没有限制)
            * directory - 存储Session文件的路径
            PersistentManager提供了把Session对象保存到Session store中的管理器,Tomcat目前提供了两种Store的实现方式方式,分别为org.apache.Catalina.FileStore,将Session对象以本地文件的方式存储在指定目录中;org.apache.Catalina.JDBCStore,将Session对象存储在指定的数据库中,本文以文件的形式进行演示,并且本文对于PersistentManager 和 Session store 的配置,原理没有做深入解析,只是做Session的持久化功能说明。
6. HttpSessionActivationListener同样是用于监控实现类本身,当实现类对象bean被添加到session中(session.setAttribute())后,在session被序列化(钝化)到文件时,sessionWillPassivate方法将被调用(只有保存到Session中的对象才会被监听到),参数HttpSessionEvent含有Session的相关信息,由于现类对象bean会被进行序列化操作,所以实现类同时需要实现Serializable接口。
public class MyHttpSessionActivationListener implements HttpSessionActivationListener, Serializable {
    private String name;

    public MyHttpSessionActivationListener(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        System.out.println("MyHttpSessionActivationListener sessionWillPassivate(session 即将超时,bean被序列化到本地) and sessionId = " + session.getId() + ", " + this.toString());
    }

    public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        System.out.println("MyHttpSessionActivationListener sessionDidActivate(session 即将激活,bean被反序列化到内存) and sessionId = " + session.getId() + ", " + this.toString());
    }

    @Override
    public String toString() {
        return "MyHttpSessionActivationListener{" +
                "name=‘" + name + ‘\‘‘ +
                ‘}‘;
    }
}

JSP代码:
<%@ page import="com.MyHttpSessionActivationListener" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello HttpSessionActivationListener</h2>
<p>HttpSessionActivation changes</p>
<%
    Object name = session.getAttribute("name");
    if (name == null) {
        MyHttpSessionActivationListener activationListener = new MyHttpSessionActivationListener("SessionActivationBean");
        session.setAttribute("name", activationListener);
%>
<p>session setAttribute</p>
<p><b>session.setAttribute("name", "activationListener");</b></p>
<%} else {%>
<p>session getAttribute</p>
<p>
    <b>session.getAttribute("name") : <%= name%>
    </b>
</p>
<%}%>
<hr/>
</body>
</html>


当内存中没有session信息时,通过指定sessionId访问服务器时(或者在原有页面中重新刷新时),根据sessionId.session文件(反序列化)会重新载入序列化的Session信息,同时,sessionDidActivate方法被调用,参数HttpSessionEvent中含义反序列化的Session及对象bean信息

7. 监听客户端请求Servlet Request对象的监听器与ServletContext监听器同样类似,分别对应ServletRequestListener 和 ServletRequestAttributeListener,它们的接口方法与ServletContext接口方法也是类似,此处不再赘述,另外,对于ServletRequest的操作可通过ServletRequestEvent和ServletRequestAttributeEvent参数进行获取,贴出代码。
 ServletRequestListener 监听器
@WebListener
public class MyServletRequestListener implements ServletRequestListener {
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        ServletRequest servletRequest = servletRequestEvent.getServletRequest();
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String attribute = (String) request.getAttribute("name");
        System.out.println("MyServletRequestListener requestDestroyed and request attribute : " + attribute);
    }

    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        ServletRequest servletRequest = servletRequestEvent.getServletRequest();
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        request.setAttribute("name", "requestInitialized");
        System.out.println("MyServletRequestListener requestInitialized and request set attribute : [name = requestInitialized]");
    }
}

JSP代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello ServletRequestListener!</h2>
<p>ServletRequestListener changes</p>
<p>request get init attribute</p>
<p><b>request.getAttribute("name");</b></p>
<%
    String name = (String) request.getAttribute("name");
%>
<p>request init value is : <%= name%>
</p>
<hr/>
<p>request.setAttribute</p>
<p><b>request.setAttribute("name", "add ServletRequestListener value");</b></p>
<%
    request.setAttribute("name", "add ServletRequestListener value");
%>
<hr/>
</body>
</html>

ServletRequestAttributeListener监听器
@WebListener
public class MyServletRequestAttributeListener implements ServletRequestAttributeListener {
    public void attributeAdded(ServletRequestAttributeEvent event) {
        Object value = event.getValue();
        System.out.println("MyServletRequestAttributeListener attributeAdded and content is : " +
                event.getName() + " = " + value);
    }

    public void attributeRemoved(ServletRequestAttributeEvent event) {
        Object value = event.getValue();
        System.out.println("MyServletRequestAttributeListener attributeRemoved and content is : " +
                event.getName() + " = " + value);
    }

    public void attributeReplaced(ServletRequestAttributeEvent event) {
        Object value = event.getValue();
        System.out.println("MyServletRequestAttributeListener attributeReplaced and content is : " +
                event.getName() + " = " + value);
    }
}

JSP代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello ServletRequestAttributeListener!</h2>
<p>ServletRequestAttributeListener changes</p>
<p>request get init attribute</p>
<p><b>request.getAttribute("name");</b></p>
<%
    String name = (String) request.getAttribute("name");
%>
<p>request init value is : <%= name%>
</p>
<hr/>
<p>request.setAttribute</p>
<p><b>request.setAttribute("name", "add ServletRequestListener value");</b></p>
<%
    request.setAttribute("name", "add ServletRequestListener value");
%>
<hr/>
<p>request replace attribute</p>
<p><b>request.setAttribute("name", "add ServletRequestListener replace value");</b></p>
<%
    request.setAttribute("name", "add ServletRequestListener replace value");
%>
<hr/>
<p>request remove attribute</p>
<p><b>request.removeAttribute("name");</b></p>
<%
    request.removeAttribute("name");
%>
<hr/>
</body>
</html>

总结

第一次以博客的形式记录了自己学习web listener的经过,与之前的使用云笔记相比,发现自己需要提升的不仅仅是对各种技术的学习和掌握,对于自己的表达能力更需要进行训练和提升,虽然只是把listener的各个demo实例以及自己的理解记录下来,还是进行修修补补的更改了很多次。万事总有开头,每一天的点滴进步,才能成就非凡的卓越。

原文地址:http://blog.51cto.com/8950379/2059612

时间: 2024-10-09 16:24:17

java 学习之路 - web监听器的相关文章

mapxtreme java学习之路(1)——.dwg转.tab再转.gst详细教程

[背景] 因为项目的需要,需要在java web 项目中使用到地图,厂家提供的是dwg格式的地图,而我们采用的是mapxtreme java技术,所以先要把dwg格式的地图转成mapxtreme java可以解析的格式,即gst格式.关于这方面的资料,网上甚少,加上软件难找,中间走了不少弯路.基于mapxtreme java以后可能还要能到,dwg转gst的过程也必不可少,所以在这里整理一下整个转化过程.如果大家有更好的转化方法,欢迎讨论. [环境] windows xp 32 位 的虚拟机.

java学习之路—初级阶段(迷茫的大学)

本人现在大三,三本院校,电子信息专业.大三下学期才开始定位软件方向.真的是越上学越迷茫,真的不知道去干嘛,本专业本身就可以分软硬件两个方向,可我们都要学.最迷茫的时候,一直在玩游戏,因为真的不知道要去干嘛.知道的太少,心态消极,,,,,后来开始上网才知道原来很多人大学生和我一样迷茫,我们真的没了方向.当然也有些人一上大学就知道自己要干嘛,并且一直努力着.有时候真的很羡慕他们,当别人刚开始起步的时候,或许他们已经登上了顶峰,当然也怪自己的愚昧无知啦.好吧,感慨有点多,呵呵. 在网上混了好几天之后,

java学习之路之javaSE基础1

<h2>java学习之路之javaSE基础1</h2> <div> ###01.01_计算机基础知识(计算机概述)(了解)* A:什么是计算机?计算机在生活中的应用举例 * 计算机(Computer)全称:电子计算机,俗称电脑.是一种能够按照程序运行,自动.高速处理海量数据的现代化智能电子设备.由硬件和软件所组成,没有安装任何软件的计算机称为裸机.常见的形式有台式计算机.笔记本计算机.大型计算机等. * 应用举例 * 1:科学计算 * 2.数据处理 * 3.自动控制 *

Java学习之路(二)--Thinking in Java

针对昨天Java学习之路(一)--Thinking in Java中的类的静态方法不能访问创建非静态类,给出了将内部类修改成为static静态类,操作方便简单.现在给出第二种不需要添加删除的另一种极为高效的方式.可以将内部类从你所创建的类中复制粘贴到类外,作为一个外部类,在static主方法中就可以创建类的引用了. 源代码如下: ? class test{ int s; char c; } public class test1 { public static class test{ int s;

Java学习之路:1、HelloWorld

似乎每种语言都是从HelloWorld开始的,所以,我的第一个java程序,也应该是这样开始的! 1.配置好jdk后,开始编写HelloWorld.java package second;//这个应该在我的理解就相当于php的命名空间 public class HelloWorld {//如同php中的声明一个类,不过php是不需要加public这样的类型修饰符 public static void main(String[] args){//声明一个方法,不过不懂的是为什么一定要static:

Java学习之路:2、Mysql 链接与查询

1.事实上我发现有了php的功力在里面,学习java起来还是不是很费劲,只是java就没有面向过程这一说 package second; import java.sql.*;//导入 public class mysql { public static void main(String[] args) throws SQLException{ String driver = "com.mysql.jdbc.Driver";//声明要被导入的类 String dsn = "jd

黑马程序员 【】java学习之路——TCP(三)客户端上传文件到服务器

------- <a href="http://www.itheima.com" target="blank">android培训</a>.<a href="http://www.itheima.com" target="blank">java培训</a>.期待与您交流! ---------- import java.io.*; import java.net.*; class

JAVA学习之路:不走弯路,就是捷径

转自:http://blog.csdn.net/jaketseng/archive/2007/12/01/1910483.aspx 软件开发之路是充满荆棘与挑战之路,也是充满希望之路.JAVA学习也是如此,没有捷径可走.梦想像<天龙八部>中虚竹一样被无崖子醍醐灌顶而轻松获得一甲子功力,是很不现实的.每天仰天大叫"天神啊,请赐给我一本葵花宝典吧",殊不知即使你获得了葵花宝典,除了受自宫其身之苦外,你也不一定成得了" 东方不败",倒是成"西方失败&

(转)如何学习Java技术?谈Java学习之路

51CTO编者注:这篇文章已经是有数年“网龄”的老文,不过在今天看来仍然经典.如何学习Java?本篇文章可以说也是面对编程初学者的一篇指导文章,其中对于如何学习Java的步骤的介绍,很多也适用于开发领域其他技能的学习. [在原先<学好Java之我见>的基础上重新整理而成] Java - 近10年来计算机软件发展过程中的传奇,其在众多开发者心中的地位就如“屠龙刀”.“倚天剑”. Java是个平台,我只想说说我对学好Java的一点看法,希望对初学者有所帮助. 1. 思考一下 学习Java之前,先别