javaweb — 监听器

前言

在web应用中,有时候你想在web应用程序启动或关闭的时候执行一些任务,或者你想见他Session的创建和关闭等你就可以通过监听器来实现。那么Servlet来8个监视器接口,下面一一讲解一下。

1:ServletContextListener和ServletContextAttributeListener

1.1:ServletContextListener主要用于容器的启动和关闭时候进行监听。有2个方法分别用于监听容器启动和关闭。比喻我们在容器启动的时候做数据库连接的初始化。容器关闭时候可以通知从来启动另一个容器保证应用程序的稳定运行

代码如下

public class MyServletContextListener implements ServletContextListener{

    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("Servlet上下文对象开始进行初始化");        
    }

    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("Servlet上下文对象开始销毁");
    }
}

web.xml配置(下同)

 <listener>
        <listener-class>com.lp.listensrs.MyServletContextListener</listener-class>
 </listener>

1.2:ServletContextAttributeListener主要用来监听上下文对象属性变化的主要有3个方法分别来监听添加属性,删除属性,以及属性值得替代。

public class MyServletContextAttributeListener implements ServletContextAttributeListener{

    public void attributeAdded(ServletContextAttributeEvent scab) {        
        System.out.println("添加的ServletContext属性是"+scab.getName());
    }

    public void attributeRemoved(ServletContextAttributeEvent scab) {
        System.out.println("删除的ServletContext属性是"+scab.getName());
    }

    public void attributeReplaced(ServletContextAttributeEvent scab) {
        System.out.println("属性值进行替代");
    }
}

然后我们在jsp文件上加上

       application.setAttribute("sqlName", "admin");
        application.setAttribute("sqlName", "replaceadmin");
        application.removeAttribute("sqlName");

运行可以看到结果为


在这里插入图片描述

1.2:ServletContextAttributeListener主要用来监听上下文对象属性变化的主要有3个方法分别来监听添加属性,删除属性,以及属性值得替代。

public class MyServletContextAttributeListener implements ServletContextAttributeListener{

    public void attributeAdded(ServletContextAttributeEvent scab) {        
        System.out.println("添加的ServletContext属性是"+scab.getName());
    }

    public void attributeRemoved(ServletContextAttributeEvent scab) {
        System.out.println("删除的ServletContext属性是"+scab.getName());
    }

    public void attributeReplaced(ServletContextAttributeEvent scab) {
        System.out.println("属性值进行替代");
    }
}

然后我们在jsp文件上加上

application.setAttribute("sqlName", "admin");
application.setAttribute("sqlName", "replaceadmin");
application.removeAttribute("sqlName");

运行可以看到结果为


在这里插入图片描述

2:ServletRequestListener和ServletRequestAttributeListener

2.1:ServletRequestListener主要用来监听httpRequest对象请求和响应的。通过这个监听器可以监听应用程序中每个HTTP请求的数量。代码如下

public class MyServletRequestListener implements ServletRequestListener{
    public void requestDestroyed(ServletRequestEvent sre) {
        System.out.println("对请求进行响应");
    }

    public void requestInitialized(ServletRequestEvent sre) {
        HttpServletRequest request=(HttpServletRequest)sre.getServletRequest();
        String url=request.getRequestURL().toString();
        System.out.println("收到Request请求"+url);
    }
}

然后我们可以看结果
在这里插入图片描述

2.1:ServletRequestAttributeListener这个是监听Request属性的变化和ServletContent基本一样。代码如下

public class MyServletRequestAttributeListener implements ServletRequestAttributeListener
{

    public void attributeAdded(ServletRequestAttributeEvent srae) {
        System.out.println("添加的属性:"+srae.getName());
    }

    public void attributeRemoved(ServletRequestAttributeEvent srae) {
        System.out.println("删除的属性:"+srae.getName());
    }

    public void attributeReplaced(ServletRequestAttributeEvent srae) {
        String str =MessageFormat.format(
                "ServletRequest域对象中替换了属性:{0}的值"
                ,srae.getName());
        System.out.println(str);
    }
}

3:HttpSessionListener、HttpSessionAttributeListener、HttpSessionBindingListener

3.1:HttpSessionListener主要目的是监听Session的创建和消耗的。这里只写一个简单的例子

public class MyHttpSessionListener implements HttpSessionListener{
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("Session创建,Session的Id为"+se.getSession().getId());        
        
    }

    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("Session销毁");
        
    }
}

3.2:HttpSessionAttributeListener、HttpSessionBindingListener这两个我重点说下,前者主要是监听整个应用程序Session属性的变化,而后者主要是自身属性来实现的,以便属性知道他何时添加到一个Session中,或者这个属性从Session删除,(HttpSessionBindingListener并不需要在xml中进行配置)现在来演示这个HttpSessionBindingListener。

我们现在做个简单的在线人数统计。

首先做个userList来存储上线的人数,采用单例模式,同时使用vector来避免线程安全问题。代码如下

public class UserList {

    private static final UserList userList=new UserList();
    private Vector<String> vector;
    public UserList()
    {
        vector=new Vector<String>();
    }
    public static UserList getInstance(){
        return userList;
    }
    public void addUser(String name){
         if(name!=null&&name!=""){
             vector.addElement(name);
         }
    }
    public void removeUser(String name){
        if (name!=null&name!="") {
            vector.remove(name);
        }
    }
    public Enumeration<String> getUserList(){
        return vector.elements();
    }
    public int getUserCount(){
        return vector.size();
    }
}

然后在定义一个UserBean来实现HttpSessionBindingListener从而达到当UserBean对象加入Session时调用valueBound方法删除UserBean对象时候调用valueUnbound方法。

public class UserBean implements HttpSessionBindingListener{

    private String userName;
    private UserList ul=UserList.getInstance();
    public UserBean(){};
    public UserBean(String name){
        this.userName=name;
    }
    public void valueBound(HttpSessionBindingEvent event) {
        ul.addUser(userName);
        System.out.println("被调用");
    }

    public void valueUnbound(HttpSessionBindingEvent event) {
        ul.removeUser(userName);
        System.out.println("移除被调用");
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

}

然后我们在来定义一个Servlet来用户登录并且把UserBean对象加入Session中如下

public class OnlineUserServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public OnlineUserServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        String userName=request.getParameter("userName");
        String pwd=request.getParameter("password");
        if (userName==null||userName==""||pwd==null||pwd=="") {
            response.sendRedirect("login.html");
            return;
        }
        HttpSession session=request.getSession();
        UserBean userBean=(UserBean)session.getAttribute("user");
        UserList ul=UserList.getInstance();
        if (userBean==null||!userName.equals(userBean.getUserName())) {
            userBean=new UserBean(userName);
            session.setAttribute("user", userBean);
        }
        response.setContentType("text/html;charset=gb2312");
        PrintWriter out=response.getWriter();
        out.println("欢迎用户<b>"+userName+"</b>登录");
        
        out.println("<br>当前在线用户列表</br>");
        Enumeration<String> enums=ul.getUserList();
        int i=0;
        while (enums.hasMoreElements()) {
            out.println(enums.nextElement());
            out.println("&nbsp;&nbsp;&nbsp;");
            if(i++==10){
                out.println("<br>");
            }
        }
        out.println("<br>当前在线人数:"+i);
        out.println("<p><a href='logout'>退出登录</>");
        out.close();

    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

然后在写一个Servlet退出,把UserBean从Session中删除

public class LogOutServlet extends HttpServlet{
    private static final long serialVersionUID = 1L;
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=gb2312");
        HttpSession session=request.getSession();
        UserBean userBean=(UserBean)session.getAttribute("user");
        session.removeAttribute("user");
        PrintWriter out=response.getWriter();
        out.println("<html><head><title>退出登录</title></head><body>");
        out.println(userBean.getUserName()+"你已经退出登录");
        out.println("<a href='index.html'>重新登录</a>");
        out.println("</body></html>");
        out.close();
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

最后写一个index.html登录页面

<form action="online" method="post">
        <table>
            <tr>
                <td>用户名:<input type="text" name="userName" /></td>
                <td>密码:<input type="password" name="password" /></td>
                <td><input type="submit" value="提交" /></td>
            </tr>
        </table>
</form>

先用火狐浏览器登录结婚


在这里插入图片描述

然后我在用谷歌浏览器登录


在这里插入图片描述
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容

  • 1 监听器 所谓监听器实际就是一个Java程序,功能是监听另一个Java对象的变化(如对象创建、方法调用、属性变化...
    对易_ce65阅读 63评论 0 0
  • JavaWeb中八大监听器 域对象监听器 1.ServletContextListener2.ServletCon...
    测试员阅读 254评论 0 0
  • 1. 监听器Listener 监听器就是监听某个对象的状态变化的组件。监听器的相关概念事件源: 被监听的对象(三个...
    Lilbetter_0326阅读 1,506评论 0 0
  • 1.监听器的简介 1.监听器: 专门用于对其他对象身上发生的事件或状态改变进行监听或相应处理的对象,当被监视的对象...
    一颗白菜_阅读 381评论 0 1
  • 按监听的对象划分 1.用于监听应用程序环境对象(ServletContext)的事件监听器,实现ServletCo...
    pinnuli阅读 488评论 0 0