Day25-Listener

本文详细介绍了JavaWeb中的监听器概念及其应用场景,包括监听三个域对象的创建与销毁、属性变更及JavaBean状态改变等内容。

监听器Listener

概述:
监听器就是一个Java类,用来监听其他的JavaBean的变化。
主要是监听三个域对象:request/session/(servletContext)application
我们学习的JavaWeb中的监听器
Servlet中提供了8个监听器

应用:
主要在Swing编程,java桌面
在Android大量应用
js:点击事件

相关术语:
​ 事件源 :被监听的对象.(目标对象) 明星
监听器对象:监听的对象. 狗仔
注册(绑定):将”监听器”对象注册给”事件源”. 当事件源发生某些行为,监听对象将被执行 狗仔在
事件:事件源行为的称呼. 出轨
​ 事件对象:在”监听器对象”中获得”事件源”

分类:
1)监听三个域对象的创建和销毁
2)监听域对象的属性变更(属性添加,属性移除,属性替换)
3)监听HttpSession中JavaBean状态的改变的

编写步骤:
1)编写一个类
2)注册

四大域对象:
pageContext 当前页面
主要是当前的页面的上下文
request 当前请求
创建: 请求达到的时候
销毁: 响应生成的时候
作用: 可以在一次请求中传递参数
session 当前会话
创建: 第一次调用request.getSession()
销毁: 1.30分钟超时, 2.调用invalidate(). 3.服务器非正常关闭
作用: 存放用户私有数据
application 当前工程
创建: 服务器启动的时候/工程被添加到服务器中的时候
销毁: 服务器正常关闭的时候/工程被移除的时候
作用: 存放工程内需要共享的数据

Javaweb的监听器:
监听ServletContext,HttpSession,ServletRequest三个域对象
事件源和监听器的绑定的过程,通过配置web.xml来完成


第一类监听器:监听三个域对象的创建和销毁

这里写图片描述
1.1 ServletContextListener 常用!
(listener属于web层)
ServletContext(application ) 当前工程
创建: 服务器启动的时候/工程被添加到服务器中的时候
销毁: 服务器正常关闭的时候/工程被移除的时候
作用: 存放工程内需要共享的数据
应用:
初始化工作,加载配置文件,ContextLoaderListener
1)创建,实现接口ServletContextListener

public class ServletContextLis implements ServletContextListener {
      @Override
      public void contextDestroyed(ServletContextEvent arg0) {
           System.out.println("servletContextLister销毁了");
      }
      @Override
      public void contextInitialized(ServletContextEvent arg0) {
           System.out.println("servletContextLister启动了");
      }
}

2)绑定,注册
在web。xml中

  <listener>
  <!-- 全限定名 -->
        <listener-class>com.itheima.servletContext.ServletContextLis</listener-class>
  </listener>

1.2 HttpSessionListener(监听session创建和销毁)
session 当前会话
创建: 第一次调用request.getSession()
服务器第一次访问servlet的时候,并且调用getSession()方法的时候,如果访问的是jsp就直接创建
销毁: 1.30分钟超时, 2.调用invalidate(). 3.服务器非正常关闭
作用: 存放用户私有数据
(当第一次请求servlet的时候不一定调用,第一次请求jsp才一定调用,意思就是说,服务器启动的时候,如果没有index.jsp这类主页面,而且一定要是jsp文件,因为session是jsp的内置对象,如果直接请求html文件也是不会调用的。就是没有请求到页面的情况下,session是不会创建的,只有请求到页面才会创建session)
服务器正常关闭的话,session会序列化到磁盘上,重开的时候就反序列化到服务器中。磁盘上的文档消失
这里写图片描述

public class HttpSessionLis implements HttpSessionListener {

      @Override
      public void sessionCreated(HttpSessionEvent arg0) {
           System.out.println("sessionListener创建了");
      }

      @Override
      public void sessionDestroyed(HttpSessionEvent arg0) {
           System.out.println("sessionListener销毁了");
      }
}

  <listener>
        <listener-class>com.itheima.httpsession.HttpSessionLis</listener-class>
  </listener>

1.3 servletRequestListener
request 当前请求
创建:来了请求
销毁:处理这个请求(收到了请求,不准确的说法是响应这个请求的时候)
作用: 可以在一次请求中传递参数

public class ServletRequestLis implements ServletRequestListener {

      @Override
      public void requestDestroyed(ServletRequestEvent arg0) {
           System.out.println("servletRequestListener销毁了");
      }

      @Override
      public void requestInitialized(ServletRequestEvent arg0) {
           System.out.println("servletRequestListener创建了");
      }

}
  <listener>
    <listener-class>com.itheima.servletRequest.ServletRequestLis</listener-class>
  </listener>

第二类监听器:监听三个域对象的属性变更的监听器(属性添加,属性移除,属性替换)

这里写图片描述

2.1 ServletContextAttributeListener
监听ServletContext对象中的属性变更的监听器
这里写图片描述

2.2HttpSessionAttributeListener
这里写图片描述

2.3 ServletRequestAttributeListener
这里写图片描述

第三类监听器:监听HttpSession中的JavaBean状态改变的监听器

监听session中JavaBean状态改变的监听器
自己监听自己,自己感知在session中的状态(JavaBean中继承接口)
这类监听器不用配置

接口是这个Bean来实现

1)HttpSessionBindingListener
监听HttpSession中的JavaBean的绑定和解除状态
(感知是否被session调用setAttribute()存入了,是否被session移除了)
这里写图片描述

public class User implements HttpSessionBindingListener{
      private String name;
      private int age;

      public User() {
      }

      public User(String name, int age) {
           this.name = name;
           this.age = 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;
      }

      @Override
      public void valueBound(HttpSessionBindingEvent event) {
           System.out.println("我被session 绑定了(存进去了)...");
          //调用session.setAttribute("user",user);的时候就会启动
      }

      @Override
      public void valueUnbound(HttpSessionBindingEvent event) {
           System.out.println("我被session 解绑了(移除了)...");
          //调用session.removeAttribute("user");的时候就会启动

      }
}

2)httpSessionActivationListener
监听httpSession中JavaBean的钝化(序列化)和活化(反序列化)的状态
序列化:java对象编程二进制序列的过程(服务器要正常关闭)
反序列化:二进制序列转化成为java对象的过程。
这里写图片描述
反序列化会失败,需要实现Serializable
标准JavaBean:
私有字段
提供公共的set、get方法
提供无参数的构造方法
实现Serializable(通常省略了,出现了问题的时候加上去)


定时任务 Timer

这里写图片描述
JDK提供了工具类Timer,用作定时任务,可安排执行任务一次,或者定期重复执行。

创建Timer对象:

Timer timer = new Timer();

重要api:
这里写图片描述


案例:从现在开始,每个1s打印一次时间

public class TimerDemo {

      public static void main(String[] args){

           Timer timer = new Timer();
           timer.schedule(new TimerTask() {

                 @Override
                 public void run() {
                      System.out.println(new Date().toLocaleString());

                 }
           }, new Date(), 1000);
      }
}

案例:3秒后,每个一秒打印一次时间


Calendar日历对象

构造方法是受保护的,不能够直接new出来。要用静态方法getInstance()来获取

1)获取对象

2)获得时间。get()
设置时间。set()

注意:月份需要加1,外国的0代表1月

      @Test
      public void test01(){
           Calendar calendar = Calendar.getInstance();

           //2.1获得年月日
           System.out.println(calendar.get(Calendar.YEAR));
           //月份需要注意一下,0代表1月
           System.out.println(calendar.get(Calendar.MONTH));
           System.out.println(calendar.get(Calendar.DATE));

           //2.1获得时 分 秒
           System.out.println(calendar.get(Calendar.HOUR_OF_DAY));
           System.out.println(calendar.get(Calendar.MINUTE));
           System.out.println(calendar.get(Calendar.SECOND));
      }

3)把Calendar转换成为date对象

           Date time = calendar.getTime();
           System.out.println(time.toString());

案例:从明天凌晨开始打印时间:

        Timer timer = new Timer();

        //设置明日凌晨的时间
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DATE, 6);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        System.out.println(calendar.getTime().toLocaleString());

        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                System.out.println(new Date().toLocaleString());

            }
        }, calendar.getTime(), 1000);

邮件

发邮件协议:SMTP协议
收邮件协议:POP3协议

3.1邮件服务器
- 要在Internet上提供电子邮件功能,必须有专门的电子邮件服务器。例如现在Internet很多提供邮件服务的厂商:sina、sohu、163 , QQ等等他们都有自己的邮件服务器。
- 这些服务器类似于现实生活中的邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中。
- 邮件服务器,按照提供的服务类型,可以分为发送邮件的服务器和接收邮件的服务器。

3.2电子邮箱

  • 电子邮箱(E-mail地址)的获得需要在邮件服务器上进行申请 ,确切地说,电子邮箱其实就是用户在邮件服务器上申请的一个帐户。用户在邮件服务器上申请了一个帐号后,邮件服务器就会为这个帐号分配一定的空间,用户从而可以使用这个帐号以及空间,发送电子邮件和保存别人发送过来的电子邮件。
    对于用户来,电子邮箱就是一个账号
    就是在服务器开辟了一块空间

3.3协议
规定邮件数据的格式

3.3.1 SMTP协议-发邮件协议

  • 全称为Simple Mail Transfer Protocol(简单邮件传输协议),它定义了邮件客户端软件与SMTP服务器之间、以及两台 SMTP服务器之间的通讯规则。
  • 端口号:25.

3.3.2 POP3协议-收邮件协议
- 全称为Post Office Protocol(邮局协议),它定义了邮件客户端软件与POP3服务器的通讯规则。
- 端口号:110.
流程:
这里写图片描述


案例:用java语言发送邮件(了解):

步骤:​
1.导入mail.jar,使用工具类MailUtils.java
​ 2.调用api
​ 三个核心对象
​ session对象, 登录
​ message对象(设置收件人,设置主题,设置内容)
​ transport对象:收件人信息


public class MailUtils {

    public static void sendMail(String email, String emailMsg)
            throws AddressException, MessagingException {
        // 1.创建一个程序与邮件服务器会话对象 Session

        Properties props = new Properties();
        //设置发送的协议
        props.setProperty("mail.transport.protocol", "SMTP");

        //设置发送邮件的服务器
        props.setProperty("mail.host", "localhost");
        props.setProperty("mail.smtp.auth", "true");// 指定验证为true

        // 创建验证器
        Authenticator auth = new Authenticator() {
            public PasswordAuthentication getPasswordAuthentication() {
                //设置发送人的帐号和密码
                return new PasswordAuthentication("service@store.com", "123456");
            }
        };

        Session session = Session.getInstance(props, auth);

        // 2.创建一个Message,它相当于是邮件内容
        Message message = new MimeMessage(session);

        //设置发送者
        message.setFrom(new InternetAddress("service@store.com"));

        //设置发送方式与接收者
        message.setRecipient(RecipientType.TO, new InternetAddress(email)); 

        //设置邮件主题
        message.setSubject("用户激活");
        // message.setText("这是一封激活邮件,请<a href='#'>点击</a>");

        //设置邮件内容
        message.setContent(emailMsg, "text/html;charset=utf-8");

        // 3.创建 Transport用于将邮件发送
        Transport.send(message);
    }
}

案例: 在项目启动的时候设定第二天给过生日的客户发送生日祝福邮件

思路:
- 创建数据库和实体
- 创建BirthdayLis实现ServletContextListener,在contextInitialized()方法里面:
​ //明日凌晨,给过生日的人,发送邮件
​ 创建一个定时任务schedule(TimerTask task, new Date(), 1000):
​ 第一个参数:调用业务,获得过生日的人(List),遍历list,给每一个过生日的人发邮件
- ​ 第二个参数:明日凌晨(明日凌晨的时间距离当前的时间)
​ 第三个参数:一天

依赖两个工具:
MailUtils
DateUtils

public class ServletContextLis implements ServletContextListener {

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        System.out.println("服务器启动了");
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                try {
                    UserService us = new UserService();
                    List<User> list = us.findUser();
                    System.out.println(list.size());
                    for (User user : list) {
                        MailUtils.sendMail(user.getEmail(), "生日快乐:"+user.getUsername());
                        System.out.println(user);
                    }
                } catch (Exception e) {
                    System.out.println("查询用户失败");
                    e.printStackTrace();
                }

            }
//        }, DateUtils.getDelayTime(), DateUtils.getOneDay());
        }, 5000, DateUtils.getOneDay());

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值