[笔记]javaWeb监听器

什么是监听器?

学习javaweb时我们会用到很多种域对象,
request域,session域,以及application域这三种时servlet中的三大域对象;
每一个域中都可以存放一些信息,但是是有针对性的,并不是随便放置的,这个暂且不提;

今天主要学习的是监听器------->
什么是监听器?

类似于前端的事件绑定,java中的监听器用于监听web应用中某些对象、信息的创建、销毁、增加,修改,删除等动作的发生,然后作出相应的响应处理。当范围对象的状态发生变化的时候,服务器自动调用监听器对象中的方法。常用于统计在线人数和在线用户,系统加载时进行信息初始化,统计网站的访问量等等。

监听器的分类

按监听的对象划分

a.ServletContext对象监听器

b.HttpSession对象监听器

c.ServletRequest对象监听器

按监听的事件划分

a.对象自身的创建和销毁的监听器

b.对象中属性的创建和消除的监听器

c.session中的某个对象的状态变化的监听器

java中一共给我们提供了八个监听器接口,分别用于监听三个域对象,每个监听器都有专门监听的事件

Request域监听器

监听器并不是一个有实体方法的类,而是一个接口,接口中的方法需要我们去实现;

创建一个Request域监听器----->
实现requestInitialized和requestDestroyed方法

import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;

public class MyListener_demo2  implements ServletRequestListener {
  
//监听request对象创建
    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        ServletRequest servletRequest = sre.getServletRequest();//可以得到请求对象;
        System.out.println(servletRequest.hashCode());
        System.out.println(servletRequest);
//        通过请求对象做出一些处理
        System.out.println(servletRequest.getAttribute("user"));//取出域中的信息
        
    }
    //监听request对象销毁
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        ServletRequest servletRequest = sre.getServletRequest();
        System.out.println(servletRequest.hashCode()+"请求对象销毁了");
        System.out.println(servletRequest+"请求对象销毁了");
    }
}

创建好之后还需要将监听器部署到项目中;

配置监听器—

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

  <!--  //配置监听器-->
   <listener>
        <listener-class>MyListener.MyListener_demo2</listener-class>
    </listener>
    
</web-app>

创建servlet

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/MyServlet_demo01.do")
public class MyServlet_demo01  extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("servlet1----invoked");

        req.setAttribute("user","张三");
        System.out.println("请求对象1"+req.hashCode());
    }
}

部署项目后运行

在这里插入图片描述

运行后发现该监听器只能监听request对象的创建和销毁,要想监听request域中内容得增删改,那么该如何操作呢?

创建一个Request域属性监听器----->


public class MyListener_demo2  implements ServletRequestAttributeListener {


    //监听request中属性的添加
    @Override
    public void attributeAdded(ServletRequestAttributeEvent srae) {
        String name = srae.getName();
        Object value = srae.getValue();
        //获得request对象;
        ServletRequest servletRequest = srae.getServletRequest();
        System.out.println("请求行中的user="+servletRequest.getParameter("user"));
        System.out.println("请求域中添加了"+name+"="+value);
    }
    //监听request中属性的移除
    @Override
    public void attributeRemoved(ServletRequestAttributeEvent srae) {
        String name = srae.getName();
        Object value = srae.getValue();

        System.out.println("请求域中删除了"+name+"="+value);
    }
    //监听request中属性的修改
    @Override
    public void attributeReplaced(ServletRequestAttributeEvent srae) {
        String name = srae.getName();
        Object value = srae.getValue();

        System.out.println("请求域中修改了"+name+"="+value);
    }
}

创建servlet

@WebServlet("/MyServlet_demo03.do")
public class MyServlet_demo03 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

      //添加Attribute
       req.setAttribute("user","张三");
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //修改Attribute
       req.setAttribute("user","李四");
//添加新的
        req.setAttribute("password","123456");
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
//        移除
        req.removeAttribute("password");
    }
}

运行------>
在这里插入图片描述

session域监听器

跟request监听器搭建类似,实现接口然后调用方法等;
监听sessio的创建与销毁—HttpSessionListener
监听session中的属性增删改—HttpSessionAttributeListener


import javax.servlet.http.*;

public class MySessionListener_demo01  implements HttpSessionListener, HttpSessionAttributeListener {
    //监听session对象的创建

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        HttpSession session = se.getSession();
        System.out.println("哈希值为--"+session.hashCode()+"session对象创建了");

    }
    //监听session对象的销毁
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        HttpSession session = se.getSession();
        System.out.println("哈希值为--"+session.hashCode()+"session对象销毁了");
    }

//监听session中的属性添加
    @Override
    public void attributeAdded(HttpSessionBindingEvent se) {
        HttpSession session = se.getSession();
        System.out.println("哈希值为--"+session.hashCode()+"对象中增加了属性");
        System.out.println(se.getName()+"="+se.getValue());
    }
    //监听session中的属性移除
    @Override
    public void attributeRemoved(HttpSessionBindingEvent se) {
        HttpSession session = se.getSession();
        System.out.println("哈希值为--"+session.hashCode()+"对象中移除了属性");
        System.out.println(se.getName()+"="+se.getValue());
    }
    //监听session中的属性修改
    @Override
    public void attributeReplaced(HttpSessionBindingEvent se) {
        HttpSession session = se.getSession();
        System.out.println("哈希值为--"+session.hashCode()+"对象中修改了属性");
        System.out.println(se.getName()+"="+se.getValue());
    }
}

可以绑定监听器与某一个session相关联
HttpSessionBindingListener

创建一个监听器----->>>实现
HttpSessionBindingListener
HttpSessionActivationListener


import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;
@WebListener
public class MySessionBindListener_demo01 implements HttpSessionBindingListener, HttpSessionActivationListener {

//绑定事件
    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        System.out.println(event.getName());
        System.out.println(event.getValue());
        System.out.println("该监听器与"+event.getSession().hashCode()+"绑定了");

    }
//解绑事件
    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {

        System.out.println(event.getName());
        System.out.println(event.getValue());
        System.out.println("该监听器与"+event.getSession().hashCode()+"解绑了");

    }

//session钝化
    @Override
    public void sessionWillPassivate(HttpSessionEvent se) {
        System.out.println(se.getSession().hashCode()+"session钝化");
    }
    //session活化
    @Override
    public void sessionDidActivate(HttpSessionEvent se) {
        System.out.println(se.getSession().hashCode()+"session活化");
    }
}

session活化与session钝化

session是有自己生命周期的,当我们创建一个session时,在浏览器保存一个cookie,下次浏览器访问时就可以跳过一些环节,但是当session 失效时后者session被清除时(服务器重启,那么浏览器中的cookie对象也就会失效,服务器回重新生成一个session),如果服务器不想这样的化,就需要在服务器重启时 钝化session------简单的说就是将session对象序列化后写入到磁盘,—这就时session的钝化,当服务器重启时读取这个session那么服务器就会检查到浏览器发过来的cookie,这叫session的活化;

application域监听器

监听器

package MyListener;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class MyApplicationListener_demo1 implements ServletContextListener, ServletContextAttributeListener {

    @Override
    public void attributeAdded(ServletContextAttributeEvent scae) {
        System.out.println("被添加的信息---");
        System.out.println(scae.getName()+"---"+scae.getValue());
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent scae) {
        System.out.println("被移除的信息---");
        System.out.println(scae.getName()+"---"+scae.getValue());
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent scae) {
        System.out.println("被修改的信息---");
        System.out.println(scae.getName()+"---"+scae.getValue());
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println(sce.getServletContext().hashCode()+"被实例化了");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println(sce.getServletContext().hashCode()+"被销毁了");
    }
}

servlet

@WebServlet("/MyServlet_demo06.do")
public class MyServlet_demo06 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("servlet6----invoked");
        ServletContext servletContext = req.getServletContext();
        servletContext.setAttribute("username","王二麻子");
        servletContext.setAttribute("password","WangEr");
        servletContext.setAttribute("username","李代张冠");
        servletContext.removeAttribute("username");
    }
}

用request监听器记录请求日志

package MyListenerdemo;
import org.apache.log4j.Logger;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
@WebListener
public class MyListenerDemo01  implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {

    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        Logger logger = Logger.getLogger(MyListenerDemo01.class);
        ServletRequest servletRequest = sre.getServletRequest();
        HttpServletRequest req=(HttpServletRequest)servletRequest;
        String remoteHost = req.getRemoteHost();
        System.out.println(remoteHost);
        String requestURI = req.getRequestURI();
        String requestUrl = req.getRequestURL().append(requestURI).toString();
        System.out.println(requestUrl);

        SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = sdf.format(new Date());
        System.out.println(date);

//用打印流记录,但是会遇到阻塞等,比较繁琐;
        try {
            PrintWriter pw= new PrintWriter(new FileOutputStream("d:/gavin.txt"),true);
            pw.println(remoteHost+" "+requestUrl+" "+date);
            pw.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            logger.info(remoteHost+" "+requestUrl+" "+date);
        }
    }
}

用session监听器记录在线人数

package MyListenerdemo;

import javax.servlet.ServletContext;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class MySessionListener_01 implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent se) {

//        拿到session
        HttpSession session = se.getSession();
        ServletContext application = session.getServletContext();
        //查看session中是否有值
        Object attribute =  application.getAttribute("count");
//        如果count为null,说明是第一次访问
        if(attribute==null){

            application.setAttribute("count",1);
        }else{//不是第一次访问
            Integer count=(Integer)attribute;
            application.setAttribute("count",++count);
        }
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        //        拿到session
        HttpSession session = se.getSession();
        ServletContext application = session.getServletContext();

        Integer  count=(Integer)application.getAttribute("count");
        application.setAttribute("count",--count);

    }
}

session的钝化与活化监听器实现

这种方式用于用户七天之内免登录的路况!

框架搭建!!
准备一个jsp页面------->>>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
当前在线人数:${applicationScope.count}
  <form method="post" action="myServlet01.do">
    账号:<input type="text" name="username" placeholder="请输入账号">

    密码:<input type="text" name="userpwd" placeholder="请输入密码">
    <input type="submit" value="登录">
  </form>
  </body>
</html>

准备一个user实体类,

package MyPojo;

import java.io.Serializable;
import java.util.ArrayList;

public class User implements Serializable {
    private static final long serialVersionUID = 88591L;
    private String username;
    private String userpwd;

    public User() {
    }

    public User(String username, String userpwd) {
        this.username = username;
        this.userpwd = userpwd;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUserpwd() {
        return userpwd;
    }

    public void setUserpwd(String userpwd) {
        this.userpwd = userpwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", userpwd='" + userpwd + '\'' +
                '}';
    }
}

准备两个servlet,一个用于检测是否登录成功,另一个用于检测设置七天免登录是否成功

import MyPojo.User;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet(urlPatterns = "/myServlet01.do")
public class myServlet01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String userpwd = req.getParameter("userpwd");
        if ("gavin".equals(username)&&"123".equals(userpwd)){
            HttpSession session = req.getSession();
            User user= new User(username,userpwd);
            session.setAttribute("user",user);
        }else{
            resp.sendRedirect("index.jsp");
        }

    }
}

package MyServletdemo;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(urlPatterns = "/myServlet02.do")
public class myServlet02  extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
//        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=UTF-8");

        HttpSession session = req.getSession();
        Object attribute = session.getAttribute("user");
        PrintWriter writer = resp.getWriter();
        String Mes;
        if(null!=attribute){
            Mes="您已登录过!";
           
        }else{
            Mes="你还未登录!";
        }
        writer.write(Mes);
    }
}

在没有添加配置文件的时候—重启服务器后用户就需要重新登录,

添加配置文件后用户仍然处于登陆状态!

添加配置文件如下---->>
在web文件夹下添加 META-INF文件夹,然后创建Context.xml配置文件;

<?xml version="1.0" encoding="UTF-8"?>

<Context>

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

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

    </Manager>
    </Context>

之后你就会发现-----

在这里插入图片描述
原理就是服务器会在重启关闭后将session持久化到文件中,重启之后读取该文件,恢复session对象;

之前提到过session的钝化与活化,这里有一个监听器来监测session的钝化与活化-----

既然session是序列化后写入到文件中,那么 该监听器就需要实现监听器接口和实现序列化接口


import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
import java.io.Serializable;

@WebListener
public class MySessionListener_o2 implements HttpSessionActivationListener , Serializable {

    @Override
    public void sessionWillPassivate(HttpSessionEvent se) {
        HttpSession session = se.getSession();
        System.out.println("检测到session"+session.hashCode()+"钝化了");

    }

    @Override
    public void sessionDidActivate(HttpSessionEvent se) {
        HttpSession session = se.getSession();
        System.out.println("检测到session"+session.hashCode()+"活化了");
    }
}

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodeMartain

祝:生活蒸蒸日上!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值