`

day18 监听器 统计在线人数,定时销毁超时session,钝化活化session,在线列表显示和踢人功能防止用户自动登录,在线支付

阅读更多

Servlet 监听器
和过滤器一样,是Servlet开发高级应用技术

监听器:监听器就是一段java程序,用来监听另一个java对象方法调用和属性改变。
监听原理
1、存在事件源
2、提供监听器
3、为事件源注册监听器
4、操作事件源,产生事件对象,将事件对象传递给监听器,并且执行监听器相应监听方法

例如:swing开发首先制造Frame窗体,窗体本身也是一个显示空间,对窗体提供监听器,监听窗体方法调用或者属性改变
* 关闭窗体时,调用windowListener 的windowclosing() , 传递windowEvent参数,表示窗体关闭事件对象
* 事件对象操作事件源,获得事件源状态

自定义监听器案例
1、需要事件源对象 Person
2、需要提供监听器接口 PersonListener
* 监听方法接收事件对象
3、编写事件对象PersonEvet

4、在事件源中注册监听器
5、操作事件源 ----- 在事件源方法中,构造事件对象(参数当前事件源),传递事件对象给监听器监听方法
6、在监听器监听方法中,获得事件源,通过事件源对象获得相关属性

--------------------------------------------------

Servlet 规范中定义了很多监听器,用于监听Servlet三个数据域对象创建销毁和 内部数据状态改变
Servlet三种存储范围:ServletContext、HttpSession、ServletRequest

Servlet监听器分为三大类
1、数据域对象创建和销毁 监听器
2、数据域对象 属性变更监听器
3、绑定到Session中数据对象 本身状态监听器

第一部分 数据域对象创建销毁监听器 --- 监听三个与对象 (三个监听器)
1、ServletContextListener : 用来监听ServletContext对象的创建和销毁
*contextInitialized(ServletContextEvent sce)  监听创建
*contextDestroyed(ServletContextEvent sce)  监听销毁
* ServletContext对象代表全局唯一对象,每个web工程会产生一个ServletContext,服务器启动创建,服务器关闭销毁

编写监听器
步骤一:编写类实现特定监听器接口
步骤二:注册监听器,不是通过事件源,而是在web.xml 进行配置

ServletContextListener主流应用:
第一个:在服务器启动时,对一些对象进行初始化,并且将对象保存ServletContext数据范围内 --- 全局数据
第二个:对框架进行初始化 例如:Spring框架初始化通过ServletContextListener (因为监听器代码在服务器启动时执行)
第三个:实现任务调度,启动定时程序 (Timer、TimerTask) 使一个程序,定时执行
java.util.Timer 一种线程设施,用于安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。
Timer提供了启动定时任务方法 schedule
* schedule(TimerTask task, Date firstTime, long period)  用来在指定一个时间启动定时器,定期循环执行
* schedule(TimerTask task, long delay, long period)  用来在当前时间delay多少毫秒后 启动定时器
停止定时器,timer.cancel 取消任务

2、HttpSession 数据对象创建和销毁监听器 ----- HttpSessionListener
* sessionCreated(HttpSessionEvent se)  监听Session对象创建
* sessionDestroyed(HttpSessionEvent se) 监听Session对象销毁

Session 何时创建 : request.getSession()
Session 何时销毁 : 关闭服务器、Session过期、session.invalidate
* Session 过期时间通过web.xml 配置,默认时间 30分钟

3、HttpServletRequest对象的创建和销毁监听器 ---- ServletRequestListener
* requestInitialized(ServletRequestEvent sre)  监听request对象创建
* requestDestroyed(ServletRequestEvent sre) 监听request对象销毁
请求发起时创建,响应结束时销毁

问题:使用forward ---- request创建销毁几次 ----- 一次
使用sendRedirect ---- request创建销毁两次 (两次请求)

综合案例一:统计在线人数
ServletContextListener 对在线人数进行初始化
HttpSessionListener 当Session创建时 在线人数+1 ,当Session销毁时,在线人数-1
编写Servlet/JSP 访问ServletContext中保存在线人数 ---- 在JSP ${applicationScope.onlinenum }


综合案例二:定时器定时销毁超时Session对象
需求:编写定时器,每隔20秒执行一次,当发现Session对象如果1分钟没有使用,就销毁该Session对象

注意:在使用扫描删除Session对象时,保证Session的List集合长度不能改变(不能添加新的Session) ---- 同步 synchronized
编写ScannerServletContextListener 初始化Session的List集合(保存ServletContext范围),启动定时器
编写ScannerHttpSessionListener 当Session被创建时,添加List集合

第二部分 ServletContext/HttpSession/ServletRequest中保存数据 创建、修改、移除监听器
ServletContextAttributeListener  监听ServletContext中属性变化
HttpSessionAttributeListener  监听HttpSession中属性变化
ServletRequestAttributeListener 监听ServletRequest中属性变化

attributeAdded 监听属性添加 ---- 当数据范围对象没有该属性,第一次添加时调用执行 setAttribute(name,value);
attributeRemoved  监听属性移除 ---- 从一个数据范围对象删除一个已经存在属性执行 removeAttribute(name);
attributeReplaced  监听属性替换 ----- 当一个数据范围已经存在一个属性,向数据范围添加相同名称属性,触发替换方法 --- setAttribute(name,value);

--------------------------------------------------------------------------------------------------------------------------------------
第三部分 被绑定Session对象,自我状态感知监听器
被存放Session的Java对象,感知自我四种状态变化
1、被绑定
2、被解除绑定
3、被钝化 ----- 数据从内存序列化硬盘
4、被活化 ---- 数据从硬盘重新加载回内存

HttpSessionBindingListener 实现接口的java对象,感知自己被绑定到Session或者从Session中解除绑定
HttpSessionActivationListener 实现接口的java对象,感知从内存被钝化硬盘上,从硬盘被活化到内存中

* 不需要配置web.xml 监听方法调用,都是由Session自主完成的

HttpSessionBindingListener
* valueBound(HttpSessionBindingEvent event) 绑定对象方法 ---- session.setAttribute(name,Object);
* valueUnbound(HttpSessionBindingEvent event)  解除绑定方法 ----- session.removeAttribute() 、当Session对象销毁时,当中所有绑定对象解除绑定

HttpSessionActivationListener
* sessionDidActivate(HttpSessionEvent se) 感知对象被活化
* sessionWillPassivate(HttpSessionEvent se)  感知对象被钝化
使用场景:Session保存数据,很长一段时间没用,但是不能销毁Session对象,不想占用服务器内存资源 ----- 钝化(将服务器内存中数据序列化硬盘上)

钝化和活化应该由tomcat服务器 自动进行 ---- 配置tomcat
<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="it315"/>
</Manager>
</Context>

配置context有几个位置?
1、tomcat/conf/context.xml 对所有虚拟主机 所有web工程生效
2、tomcat/conf/Catalina/localhost/context.xml 对当前虚拟主机所有web工程生效
3、当前工程/META-INF/context.xml 对当前工程有效

钝化后it315目录在哪里? tomcat/work/Catalina/localhost/day18 目录中
序列化? java对象如果向被序列化 实现Serializable ---- Bean2 实现该接口


综合案例:在线列表显示和踢人功能代码
* 通过在线用户列表,得知当前哪些用户在线 (论坛、社交网站、聊天室)
* 踢人功能 (销毁登陆状态,主要管理员操作)

create table user(
   id int primary key auto_increment,
   username varchar(40),
   password varchar(40),
   role varchar(20)
);

insert into user values(null,'zhangsan','123','user');
insert into user values(null,'lisi','123','user');
insert into user values(null,'wangwu','123','user');
insert into user values(null,'zhaoliu','123','user');
insert into user values(null,'mary','123','user');
insert into user values(null,'admin','admin','admin');

准备数据库连接需要程序和jar包
1、mysql驱动、c3p0、dbutils
2、配置文件c3p0-config.xml
3、JDBCUtils 工具类

编写登陆 login.jsp --- LoginServlet --- list.jsp
对全局用户集合Map进行初始化 ---- MySerlvetContextListener
对User类实现HttpSessionBindingListener 实现绑定和解除绑定方法

Session.setAttribute("user",user); 将user绑定session ---- 触发valueBound ---- 将记录加入map
session.invalidate() ; 将user从session移除绑定 ---- 触发valueUnBound ----- 从map移除记录

---------------------------------------------------------------------------------------------------------------
在线支付:商城网络购物时,连接网银系统进行,订单付款
支付方案两种
第一种:需要将支付请求提交商城网站,网站会根据银行接入规范,生成银行需要数据,并且以重定向方式,将银行需要数据提交给银行 --- 完成支付
* 网站和银行对接,网站根据不同银行接入规范,编写不同支付调用程序 (网站开发量很大,当银行接口规范发送变动时,网站需要第一时间更新对接程序)

第二种:网站根据第三方支付公司接口规范编程,将数据提交给第三方支付公司,第三方支付公司再根据不同银行的接入规范,与各个银行对接
* 优点:网站省事了
* 缺点:有些支付公司收取年费,并且每次交易还需要提取一部分手续费用 1%
* 现金流问题 --- 当公司营业金额过大时,不建议使用支付公司

http://www.yeepay.com/ 连接易宝网站后,需要在易宝网站上对商城进行账户注册
*注册----  审核营业资格
*当注册成功后 易宝会为商家分配唯一编号、授予私钥 (进行数据加密和数字签名)

在易宝支付全过程中,有两个身份验证
1、当商城将数据发送给易宝时,需要身份验证(易宝检验请求是否来自于商城,数据是否发生篡改)
* 数字签名技术hmac码 ----- 商城获得所有订单数据后,将订单数据通过易宝提供加密算法,根据商城唯一私钥 对数据进行加密获得数字签名 hmac码
------ 商城将数据与hmac一起传递易宝 ---- 易宝采用同样方式,对订单数据,根据商家私钥进行加密获得hmac码 ,比较两个hmac是否一致
2、易宝收钱后,通知商城收到货款,商城需要身份校验 (商城检验易宝身份,数据是否发生篡改)

***** 私钥不能泄露

编写易宝在线支付程序
1、编写提交支付请求页面
* 订单号,金额,选择支付通道(编码参加易宝接口规范文档 附录“支付通道编码列表”)
* 在配置pay.html 中action 属性时,路径外网IP路径(网站需要易宝回调)
* 在www.baidu.com 中输入ip 回车,看到本地外网ip
2、PayServlet参考易宝提供接口说明 ---- 支付请求参数说明
* 将易宝需要数据和hmac提交 https://www.yeepay.com/app-merchant-proxy/node -- 完成支付
3、网银支付后,易宝会调用 回调地址 callback
支付成功回调有两种,都会以GET形式通知到在线支付请求参数中的p8_Url上:■ 浏览器重定向■ 服务器点对点通讯
* 浏览器重定向 ---- 向用户客户端展示一个付款成功页面
* 服务器点对点 ---- 易宝通知商城付款成功,修改订单状态 ---- 回复易宝success

* 进行易宝支付:1、必须公网IP 2、网银系统


今天练习重点
1、监听器原理 :事件源、监听器、事件对象 之间关系
2、Servlet提供8个监听器 三大类
案例:统计在线人数、自定Session销毁扫描器、在线用户和踢人

3、配置context 进行Session钝化(三个位置)
4、在线支付

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics