监听器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());
}
}