钝化和活化(HttpSessionActivationListener)
HttpSessionActivationListener作为JavaBean实现接口,当JavaBean添加到session中,钝化与活化都会被执行相应方法
配置以及如何触发
配置
<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="d:/session"/>
</Manager>
</Context>
参数:
- Manager —- tomcat内部对象专门进行对话工作,写死
- maxIdleSwap —- session对象n分钟不用钝化到磁盘,n符号为分钟
- Store —- tomcat提供存储功能的对象
- directory —- Session对象钝化存储的路径
触发
钝化触发
客户端对服务器发送请求,服务器request.getSession()等待n分钟,期间不对服务器发起请求,触发Session钝化操作,序列化session对象存储到磁盘上
活化触发
客户端与服务器再次进行会话,服务器reqeust.getSession(),从硬盘获取序列化的session对象,并且取出
使用方式
- JavaBean类实现HttpSessionActivationListener以及序列化接口
- 编写钝化和活化(序列化和反序列化)方法
- 将其放置到session域中
- 测试
示例
JavaBean对象
package domain;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
import java.io.Serializable;
import java.util.Date;
public class Person1 implements Serializable, HttpSessionActivationListener {
/**
* 对象被序列化前执行的方法
*
* @param httpSessionEvent
*/
@Override
public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
System.out.println(new Date() + "我被序列化了....");
}
/**
* 对象被反序列化执行的方法
*
* @param httpSessionEvent
*/
@Override
public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
System.out.println(new Date() + "我被反序列化了....");
}
}
Servlet
import domain.Person1;
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(name = "ActivationListener", urlPatterns = "/ActivationListener")
public class ActivationListenerServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取session,将实现了序列化与反序列化监听器的对象放置到session域中
HttpSession session = request.getSession();
session.setAttribute("demo",new Person1());
}
}
代码运行演示

题目
当用户很多时,怎么样对服务器进行优化?
session的钝化与活化
电子邮件
发送邮件流程

配置环境
安装邮件服务器
eyoumailserversetup.exe
安装客户端软件
foxmail.exe
使用程序发送邮件
- 导入mail的jar包
- 使用发送邮件的工具类
- 配置工具类
- 编写代码发送邮件
配置工具类
- 设置发送邮件的服务器,设置发邮件协议
- 创建验证器,将发送邮件的服务器账户密码信息传入验证器
- 将设置的信息以及验证器对象传给判断连接成功标志对象的方法getInstance()
- 创建一个Message,用于发送邮件内容,分别设置发送对象、设置发送方式和接受者、设置邮件主题、设置编码邮件信息的方式
- 发送邮件
package Utils;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
public class MailUtils {
/**
* 工具类,用于发送邮件
*
* @param email 发送目标地址
* @param emailMsg 发送邮件内容
* @throws AddressException
* @throws MessagingException
*/
public static void sendMail(String email, String subject, 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("lucy", "12345");
}//发邮件的账号的验证
};
// 连接成功的标识
Session session = Session.getInstance(props, auth);
// 2.创建一个Message,它相当于是邮件内容
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("lucy@demo.com")); // 设置发送者
message.setRecipient(RecipientType.TO, new InternetAddress(email)); // 设置发送方式与接收者
message.setSubject(subject); //设置邮件主题
// message.setText("这是一封激活邮件,请<a href='#'>点击</a>");
message.setContent(emailMsg, "text/html;charset=utf-8");
// 3.创建 Transport用于将邮件发送
Transport.send(message);
}
}
发送邮件
import Utils.MailUtils;
import javax.mail.MessagingException;
public class SendEmailDemo {
public static void main(String[] args) throws MessagingException {
MailUtils.sendMail("fy@demo.com", "小明是小鸡", "小明打不过小鸡");
}
}
测试
测试平台为qq邮箱向qq邮箱发送邮件
重新编写工具类
package Utils;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
public class MailUtils {
public static void sendMail(String email, String subject, String emailMsg,String senderEmail,String sslPWd)
throws AddressException, MessagingException {
// 1.创建一个程序与邮件服务器会话对象 Session
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "SMTP"); //发邮件协议
props.setProperty("mail.host", "smtp.qq.com"); //发邮件的服务器地址,这里设置为本地
props.setProperty("mail.smtp.auth", "true");// 指定验证为true
props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.setProperty("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.port", "465");
props.setProperty("mail.smtp.socketFactory.port", "465");
// 创建验证器
Authenticator auth = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(senderEmail, sslPWd);
}//发邮件的账号的验证
};
// 连接成功的标识
Session session = Session.getInstance(props, auth);
// 2.创建一个Message,它相当于是邮件内容
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(senderEmail)); // 设置发送者
message.setRecipient(RecipientType.TO, new InternetAddress(email)); // 设置发送方式与接收者
message.setSubject(subject); //设置邮件主题
// message.setText("这是一封激活邮件,请<a href='#'>点击</a>");
message.setContent(emailMsg, "text/html;charset=utf-8");
// 3.创建 Transport用于将邮件发送
Transport.send(message);
}
}
运行
import Utils.MailUtils;
import javax.mail.MessagingException;
public class SendEmailDemo {
public static void main(String[] args) throws MessagingException {
MailUtils.sendMail("2269841094@qq.com", "小明是小鸡", "小明打不过小鸡","939902332@qq.com","vuuofnyftjvjbfdf");
}
}
运行结果

案例
发送生日祝福的案例
步骤分析
- 编写ServletContext监听器
- 重写contextInitialized方法
- 编写模拟MySQL数据表,包含uname,uid,uemail,ubirthday,插入一个正确的user,以及一个干扰项
- 设置定时器,当服务器启动开始运行,进行查询数据库,模糊查询当天生日的用户集合,将集合返回给监听器,监听器执行任务,周期为1天
编写sql语句
# 创建数据库
CREATE DATABASE listener CHARACTER SET 'utf8';
USE listener;
# 创建表
CREATE TABLE user(
uid INT PRIMARY KEY AUTO_INCREMENT,
uusername VARCHAR(50),
upassword VARCHAR(50),
email VARCHAR(50),
birthday VARCHAR(50)
)CHARACTER SET 'utf8';
# 插入数据
INSERT INTO user (uusername, upassword, email, birthday)VALUES (
'小马哥',
'feng',
'2269841094@qq.com',
'1995-04-23'
),(
'小明',
'xiaoming',
'2760180314@qq.com',
'1995-04-24'
),(
'小花',
'xiaohua',
'2499433540@qq.com',
'1995-04-30'
);
JavaBean对象
package com.company.domain;
public class User {
/*
*
* uid INT PRIMARY KEY AUTO_INCREMENT,
* uusername VARCHAR(50),
* upassword VARCHAR(50),
* email VARCHAR(50),
* birthday VARCHAR(50)
* */
private String uusername;
private String upassword;
private String email;
private String birthday;
private int uid;
public String getUusername() {
return uusername;
}
public void setUusername(String uusername) {
this.uusername = uusername;
}
public String getUpassword() {
return upassword;
}
public void setUpassword(String upassword) {
this.upassword = upassword;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
}
Email Utils工具
package Utils;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
public class MailUtils {
public static void sendMail(String email, String subject, String emailMsg,String senderEmail,String sslPWd)
throws AddressException, MessagingException {
// 1.创建一个程序与邮件服务器会话对象 Session
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "SMTP"); //发邮件协议
props.setProperty("mail.host", "smtp.qq.com"); //发邮件的服务器地址,这里设置为本地
props.setProperty("mail.smtp.auth", "true");// 指定验证为true
props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.setProperty("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.port", "465");
props.setProperty("mail.smtp.socketFactory.port", "465");
// 创建验证器
Authenticator auth = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(senderEmail, sslPWd);
}//发邮件的账号的验证
};
// 连接成功的标识
Session session = Session.getInstance(props, auth);
// 2.创建一个Message,它相当于是邮件内容
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(senderEmail)); // 设置发送者
message.setRecipient(RecipientType.TO, new InternetAddress(email)); // 设置发送方式与接收者
message.setSubject(subject); //设置邮件主题
// message.setText("这是一封激活邮件,请<a href='#'>点击</a>");
message.setContent(emailMsg, "text/html;charset=utf-8");
// 3.创建 Transport用于将邮件发送
Transport.send(message);
}
}
Dao与数据库交互
package com.company.dao;
import Utils.DbUTils;
import com.company.domain.User;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import java.sql.SQLException;
import java.util.List;
public class SendBIrthdayBlessingListenerDao {
public List<User> getBirthdayPeoson(String format) throws SQLException {
QueryRunner queryRunner = new QueryRunner(DbUTils.get_connection_pool());
String sql = "SELECT * FROM user WHERE birthday LIKE ?";
return queryRunner.query(sql, new BeanListHandler<>(User.class), "%" + format);
}
}
ServletContextListener监听器
package birthday;
import Utils.MailUtils;
import com.company.dao.SendBIrthdayBlessingListenerDao;
import com.company.domain.User;
import javax.mail.MessagingException;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
@WebListener()
public class SendBIrthdayBlessingListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
// 设置定时器
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
// 1.从数据库获取符合模糊查询的数据
List<User> users = null;
try {
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd");
String format = dateFormat.format(new Date());
users = new SendBIrthdayBlessingListenerDao().getBirthdayPeoson(format);
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("发送邮件");
// 2.遍历集合,对用户发送邮件
if (users!= null){
for (User user:users){
try {
MailUtils.sendMail(user.getEmail(),"生日快乐!","生日快乐啊 ","939902332@qq.com","ozrmgjeevcwfbeej");
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
}
}, new Date(), 1000*60*60*24);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
结果
从服务器启动开始,一天周期进行发送邮件任务,以当天时间向数据库进行模糊查询,生日为当天的发送邮件给对方。