servlet的监听器与发送邮件
一、servlet的三大作用域与使用场景
1.三大作用域
1).request:表示一次请求,只要发出一个请求就会创建一个request
作用域:仅在当前请求中有效。
用处:常用于服务器间同一请求不同页面之间的参数传递,常应用于表单的控件值传递
request对象常用的方法有:request.setAttribute(), request.getAttribute(),
request.getParameter(),request.getParameterValues(),request.setCharEncoding(""),
request.getRealPath()
2).session:session是一次会话,服务器会为每一个会话创建一个session对象,
session中的数据可以被本次会话中的所有servlet访问,会话是从浏览器打开开始,
到关闭浏览器结束。
用处: session常用于登录验证,登录成功后浏览器会为其分配一个session键值对,
之后的访问权限判断键值对就可以了。
session对象常用的方法有:
session.setAttribute();
session.getAttribute();
session.removeAttribute();
session对象的创建:在servlet中使用HttpSession session = request.getSession();
的方式来创建,在页面中可以直接获取
session对象的销毁:可以在web.xml中配置失效时间,也可以session.invalidate();
3).application(ServletContext):application是应用程序作用域,是从程序开始运行到运行停止。
用处:保存在application作用域中的值,只要程序没有停止运行,都可以获取。
实现的办法:ServletContext ctx = session.getServletContext( ),所以可以也经常叫
做ServletContext
2.使用场景
1).请求参数级别的则是方法request中,比如条件查询
2).会话级别的数据要是用session作用域,比如说登录信息,银行账号,
3).如果数据是系统级别的,那么使用application作用域,例如在线人数
二、监听器
1.什么是监听器
监听器(Listener):是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,
当被监视的对象发生情况时,立即采取相应的行动。监听器其实就是一个实现特定接口的普通java程序,这个
程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法立
即被执行
ps:简而言之监听器就是一个能够监听程序内容或者状态是否发生改变的一个Java类,
有点类似于现实世界中大厦里的火灾报警器
补充: 与监听器相关的术语
1>事件源:指的是被监听对象(汽车)
2>监听器:指的是监听的对象(报警器)
3>事件源和监听器绑定:在汽车上安装报警器
4>事件:指的是事件源对象的改变(踹了汽车一脚)----主要功能获得事件源对象。
2.监听器的作用
1).servlet中的监听器
补充:
1>.其实servlet中的监听器主要是针对request,session,servletContext开展的
2>.监听器要想起作用则必须要有实现类,而实现类要起作用,则必须要有动作,所谓的
动作其实就是事件,所谓的事件就是与之关联的一些类
3>.servlet中一共有8个监听器接口,6个事件
8个监听器接口,6个事件
1>>.ServletContextListener接口:
[接口方法] contextInitialized()与 contextDestroyed()
[接收事件] ServletContextEvent
[触发场景] 在Container加载Web应用程序时(例如启动 Container之后),
会呼叫contextInitialized(),而当容器移除Web应用程序时,会呼叫contextDestroyed()方法。
2>>.ServletContextAttributeListener
[接口方法] attributeAdded()、 attributeReplaced()、attributeRemoved()
[接收事件] ServletContextAttributeEvent
[触发场景] 若有对象加入为application(ServletContext)对象的属性,
则会呼叫attributeAdded(),同理在置换属性与移除属性时,会分别呼叫
attributeReplaced()、attributeRemoved()。
3>>.ServletRequestListener:用于接收关于进入和超出Web应用程序范围的请求的通知
事件的接口
[接口方法] requestInitialized()与 requestDestroyed()
[接收事件] RequestEvent
[触发场景] 在request(HttpServletRequest)对象建立或被消灭时,会分别
呼叫这两个方法。
4>>.ServletRequestAttributeListener
[接口方法] attributeAdded()、 attributeReplaced()、attributeRemoved()
[接收事件] HttpSessionBindingEvent
[触发场景] 若有对象加入为request(HttpServletRequest)对象的属性,
则会呼叫attributeAdded(),同理在置换属性与移除属性时,会分别呼叫
attributeReplaced()、 attributeRemoved()。
5>>.HttpSessionListener
[接口方法] sessionCreated()与sessionDestroyed ()
[接收事件] HttpSessionEvent
[触发场景] 在session(HttpSession)对象建立或被消灭时,会分别呼叫这两个方法。
6>>.HttpSessionActivationListener
[接口方法] sessionDidActivate()与 sessionWillPassivate()
[接收事件] HttpSessionEvent
[触发场景] Activate与Passivate是用于置换对象的动作,当session对象为了
资源利用或负载平衡等原因而必须暂时储存至硬盘或其它储存器时(透 过对象序列化),所
作的动作称之为Passivate,而硬盘或储存器上的session对象重新加载JVM时所采的动
作称之为Activate,所以容 易理解的,sessionDidActivate()与
sessionWillPassivate()分别于Activeate后与将Passivate前呼叫。
7>>.HttpSessionAttributeListener
[接口方法] attributeAdded()、 attributeReplaced()、attributeRemoved()
[接收事件] HttpSessionBindingEvent
[触发场景] 若有对象加入为session(HttpSession)对象的属性,
则会呼叫attributeAdded(),同理在置换属性与移除属性时,会分别呼叫
attributeReplaced()、 attributeRemoved()。
8>>.HttpSessionBindingListener
[接口方法] valueBound()与valueUnbound()
[接收事件] HttpSessionBindingEvent
[触发场景] 实现HttpSessionBindingListener接 口的类别,其实
例如果被加入至session(HttpSession)对象的属性中,则会呼叫valueBound(),
如果被从session(HttpSession)对象的属性中移除,则会呼叫valueUnbound(),
实现 HttpSessionBindingListener接口的类别不需在web.xml中设定。
2).作用
1>.统计在线人数,利用HttpSessionLisener
2>.加载初始化信息:利用ServletContextListener
3>.统计网站访问量
4>.实现访问监控
3.监听器的案例–实现统计在线人数
代码展示:
package com.turing.manage.listeners;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* @desc 统计在线人数
* @author HYZ
* @time 2020年12月14日
*/
public class SessionListener implements HttpSessionListener{
public SessionListener() {
System.out.println("SessionListerer加载了");
}
/**
* @desc 1.session创建的时候
*/
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("session已经创建,且sessionId="+se.getSession().getId());
ServletContext ctx = se.getSession().getServletContext();
Integer numSessions = (Integer)ctx.getAttribute("numSessions");
if (numSessions==null) {
numSessions = new Integer(1);
}else {
int count = numSessions.intValue();
numSessions = new Integer(count+1);
}
ctx.setAttribute("numSessions", numSessions);
}
/**
* @desc 2.session销毁的时候
*/
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("session销毁");
ServletContext ctx = se.getSession().getServletContext();
Integer numSessions = (Integer) ctx.getAttribute("numSessions");
if (numSessions==null){
numSessions=new Integer(0);
}else{
int count=numSessions.intValue();
numSessions=new Integer(count-2);
}
ctx.setAttribute("numSessions", numSessions);
}
}
在查询展示页面给予阐释:
当前在线人数为:
<font color="red">
<%=application.getAttribute("numSessions") %>个人
</font>
4.监听器、过滤器、servlet的级别
【Listener】-> 【Filter】->【Servlet】
5.监听器之–预加载一些数据信息
代码展示:
package com.turing.manage.listeners;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* @desc 利用监听器实现预先加载一些数据
* @author HYZ
* @time 2020年12月14日
*/
public class MyLicenesListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("===servlet服务初始化(也就是tomcat正式启动成功)===");
System.out.println("1.可以预先加载一些数据");
Map<String, Object> map_listener=new HashMap<String, Object>();
map_listener.put("username", "root");
map_listener.put("password", "root");
ServletContext ctx = sce.getServletContext();
ctx.setAttribute("map_listener", map_listener);
System.out.println("2.可以在此处做一些初始化项目中对象的内容");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("===servlet服务销毁(也就是tomcat重新部署)===");
}
}
6.监听器之-Request请求监听器记录ip
代码展示:
package com.turing.manage.listeners;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
/**
* @desc 通过监听器实现记录ip--->实现黑白名单--->db,excel中
* @author HYZ
* @time 2020年12月14日
*/
public class MyServletRequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
ServletRequest request = sre.getServletRequest();
System.out.println("requestDestroyed:remoteIp:"+request.getRemoteAddr());
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
ServletRequest request = sre.getServletRequest();
System.out.println("requestInitialized:remoteIp:"+request.getRemoteAddr());
}
}
ps:
使用场景:
可以通过分析获取到的ip地址进而获取到请求的ip分布情况
三、发送邮件
1.生成长度4位的验证码工具类
代码展示:
package com.turing.bc;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* @desc 工具类:生成验证码
* @author HYZ
* @time 2020年12月14日
*/
public class CodeUtils {
//测试main函数
//public static void main(String[] args) {
// for (int i = 0; i < 10; i++) {
// CodeUtils.createdCode();
// }
//}
/**
* @desc 自定义方法--生成验证码
* @return
*/
public static String createdCode(){
String[] beforeShuffle = new String[] { "2", "3", "4", "5",
"6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H",
"I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
"U", "V", "W", "X", "Y", "Z" };
List<String> list = Arrays.asList(beforeShuffle);
Collections.shuffle(list);//自动洗牌
StringBuilder sb = new StringBuilder();
for (int i = 0; i < list.size(); i++) {
sb.append(list.get(i));
}
String afterStr = sb.toString();
String code = afterStr.substring(3,7);
System.out.println(code);
return code;
}
}
2.日期处理工具类
代码展示:
package com.turing.bc;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* @desc 日期工具类:计算两个日期之间的相差的天数
* @author HYZ
* @time 2020年12月14日
*/
public class DateUtils {
//测试main函数
//public static void main(String[] args) throws ParseException {
// String strDate = "2019-12-16";
// Date now = new Date();
// SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
// System.out.println(DateUtils.differentDaysByMillisecond(format.format(now),strDate));
// int result = DateUtils.differentDaysByMillisecond(format.format(now), strDate);
// if ((result>=0)&&(result<=5)) {
// System.out.println("提前送上生日的祝福...祝你年年有今日,岁岁有今朝");
// }else {
// System.out.println("不用发");
// }
//
//}
/**
* @desc 自定义函数--求两个日期相差的天数
* @param strDate
* @param strDate2
* @return
* @throws ParseException
*/
public static int differentDaysByMillisecond(String strDate, String strDate2) throws
ParseException {
//1.初始化日期格式化类
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//2.将传入的字符串类型的日期转变为日期类型
Date fDate = format.parse(strDate);//开始日期
Date oDate = format.parse(strDate2);//目标日期
//3.初始化日历工具类
Calendar aClaendar = Calendar.getInstance();
//4.将上面获取的日期转变为天
aClaendar.setTime(fDate);
int day1 = aClaendar.get(Calendar.DAY_OF_YEAR);
aClaendar.setTime(oDate);
int day2 = aClaendar.get(Calendar.DAY_OF_YEAR);
return day2-day1;
}
}
3.properties配置文件处理类
1>.创建一个config文件夹,且该文件夹与src是平级的,且权限也是与src的级别一样
(要构建权限级别),在该目录下创建mail.properties
2>. 在mail.properties写入一些数据
emailFrom=xxx(邮箱号)@163.com
emialFromAuthorization=网易邮箱授权码
emailRole=XX管理系统
PS:在mail.properties中要对该文件设定编码集为UTF-8,且不要再里面有过多的空格和换行
代码展示:
package com.rj.bd.utils;
/**
* @desc properties文件的处理工具类
* @author HYZ
* @time 2020年12月14日
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
public class PropertyUtils {
public static void main(String[] args) throws IOException {
System.out.println(PropertyUtils.getyInfoOfPropert("mail.properties"));
}
public static Map<String, Object> getyInfoOfPropert(String propertyPath)
throws IOException{
Map<String, Object> map = new HashMap<String, Object>();
Properties prop = new Properties();
//读取mail.properties这个文件,转变为流
InputStream inputStream =
PropertyUtils.class.getClassLoader().getResourceAsStream(propertyPath);
//把获取到的流对象转变为缓存区读对象
BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
//加载mail.properties
prop.load(bufferedReader);
//获取一个迭代器
Iterator<String> it = prop.stringPropertyNames().iterator();
while (it.hasNext()) {
String key = (String) it.next();
System.out.println(key+" : "+prop.getProperty(key));
map.put(key, prop.getProperty(key));
}
bufferedReader.close();
inputStream.close();
return map;
}
}
4.发送一封简单的文本邮件
代码展示:
package com.rj.bd.utils;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Properties;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.Message.RecipientType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
/**
* @desc 邮件发送的工具类
* @author HYZ
* @time 2020年12月14日
*/
public class EmailUtils {
//自己的邮箱
public static String sendEmailAccount = "网易邮箱";
//邮箱授权码
public static String sendEmailPwd = "网易邮箱授权码";
//收件人邮箱
public static String receiveMailAccount = "QQ邮箱";
public static void main(String[] args) throws
UnsupportedEncodingException, MessagingException {
EmailUtils.createMimeMessage(sendEmailAccount, receiveMailAccount);
}
/**
* @desc 1.自定义方法--发送简单的包含文件的邮件
* @param sendMail
* @param receiveMail
* @throws UnsupportedEncodingException
* @throws MessagingException
*/
public static void createMimeMessage(String sendMail,String receiveMail)
throws UnsupportedEncodingException, MessagingException{
//1.创建参数配置,用于连接邮件服务器的参数配置
Properties props = new Properties();
// 使用的协议(JavaMail规范要求)
props.setProperty("mail.transport.protocol","smtp");
// 发件人的邮箱的 SMTP 服务器地址
props.setProperty("mail.smtp.host","smtp.163.com");
props.setProperty("mail.smtp.auth", "true");// 需要请求认证
//2.根据配置创建会话对象,用于和邮件服务器交互
Session session = Session.getInstance(props);
session.setDebug(true);//设置为debug模式,可以查看详细的发送log
//3.创建一封邮件
MimeMessage message = new MimeMessage(session);
//4.发件人
message.setFrom(new InternetAddress(sendMail, "发件人的昵称", "UTF-8"));
//5.收件人
message.setRecipient(RecipientType.TO,
new InternetAddress(receiveMail, "接收者:xx用户", "UTF-8"));
//message.setRecipient(RecipientType.CC,
new InternetAddress(sendEmailAccount, "抄送给自己的", "utf-8"));
//6.设定主题
message.setSubject("班级作业收集情况表", "UTF-8");
//7.设定正文
message.setContent("正文...情况表", "text/html;charset=utf-8");
//8.设定发送的时间
message.setSentDate(new Date());
//9.保存设置
message.saveChanges();
//10.根据session获取邮件发送对象transport
Transport transport = session.getTransport();
//11.连接上SMTP邮件发送的服务器基站
transport.connect(sendEmailAccount,sendEmailPwd);
//12.发送邮件
transport.sendMessage(message, message.getAllRecipients());
//13.关闭连接
transport.close();
}
}
**
邮件发送未完待续…
**
版权声明:本文为TimeMoments原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。