10.监听器与MVC
监听器概述
- 监听器是Web应用程序事件模型的一部分
- Web应用中的某些状态发生改变时会产生相应的事件
- ServletContext、HttpSession、ServletRequest三个域对象引发的事件
- 域对象中的属性引发的事件
- 监听器可以接收这些事件,以便在事件发生时做出相关处理
HttpSessionListener接口
- HttpSessionListener
- sessionCreated(HttpSessionEvent event)
- sessionDestroyed(HttpSessionEvent event)
- 执行session.invalidate()方法
- session会话超时
- 在web.xml中配置监听器
ServletContextListener接口
- ServletContextListener
- contextInitialized(ServletContextEvent arg)
- contextDestroyed(ServletContextEvent arg)
监听器分类
- 根据三个域对象上的具体操作,将监听器划分为三类
- 监听三个域对象的创建和销毁事件的监听器
- 监听域对象中属性的增加、删除、替换事件的监听器
- 监听绑定到HttpSession域中的某个对象的状态的监听器,又称为感知型监听器
常用监听器接口
监听器接口 | 说 明 |
---|---|
javax.servlet.ServletContextListener | 在Servlet上下文对象初始化或销毁时得到通知 |
javax.servlet.ServletRequestListener | 在请求对象初始化时或者被销毁时得到通知 |
javax.servlet.http.HttpSessionListener | 在session创建后或者失效前得到通知 |
javax.servlet.ServletContextAttributeListener | 在Servlet上下文中的属性列表发生变化时得到通知 |
javax.servlet.ServletRequestAttributeListener | 在请求对象中的属性列表发生变化时得到通知 |
javax.servlet.http.HttpSessionAttributeListener | 在session中的属性列表发生变化时得到通知 |
javax.servlet.http.HttpSessionActivationListener | 绑定到session中,当session被钝化或者激活时得到通知 |
javax.servlet.http.HttpSessionBindingListener | 在绑定session或从session中删除时会得到通知 |
感知型监听器(如HttpSessionBindingListener)
- 特点:感知型监听器无需配置,但此对象需要和session绑定
实现用户数量的统计
实现思路:
- 创建类实现监听器接口
javax.servlet.http.HttpSessionBindingListener
- 在
valueBound()
和valueUnbound()
方法中实现用户数量的统计
valueUnbound
方法会在三种情况下自动调用
- 调用使session失效的方法:
session.invalidate()
- session超时
- 调用
setAttribute
重新设置了别的对象,或是调用removeAttribute
移除了这个属性
valueBound(HttpSessionBindingEvent arg0) {
//用户对象存入session时自动调用
//用户数量加1
}
valueUnbound(HttpSessionBindingEvent arg0) {
//用户对象从session中删除时自动调用
//用户数量减1
}
具体实现代码:
User.java
public class User implements HttpSessionBindingListener, HttpSessionListener {
private Integer id; //id
private String userCode; //用户编码
private String userName; //用户名称
private String userPassword; //用户密码
//省略getter,setter。。。
//实现感知型监听器方法
//不用额外设置,但需要和session绑定
@Override
public void valueBound(HttpSessionBindingEvent event) {
CountUser.COUNT_USER++;
System.out.println("当前在线人数:" + CountUser.COUNT_USER);
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
CountUser.COUNT_USER--;
System.out.println("当前在线人数:" + CountUser.COUNT_USER);
}
//实现非感知型监听器方法
//需要在web.xml里进行额外配置
@Override
public void sessionCreated(HttpSessionEvent arg0) {
System.out.println("执行了sessionCreated");
}
@Override
public void sessionDestroyed(HttpSessionEvent arg0) {
System.out.println("执行了sessionDestroyed");
}
}
静态工具类:CountUser.java
public class CountUser {
//设定个静态初始变量
public static int COUNT_USER = 0;
}
用于登录的Servlet:LoginServlet.java
//核心代码
//先创建session
User user = new User();
if(user != null){
//创建session
HttpSession session = request.getSession();
//存入用户session
session.setAttribute("user", user);
//设置session过期时间
session.setMaxInactiveInterval(20);
}
查询所有的Servlet:ProviderAllServlet.java
//核心代码
//再获取session
HttpSession session = request.getSession();
User user = (User)session.getAttribute("user");
request.setAttribute("user", user);
前端jsp页面:index.jsp
//在前端页面打印
<% out.print("当前在线人数为:" + CountUser.COUNT_USER); %>
非感知型监听器(如HttpSessionListener)
- 特点:非感知型监听器无需绑定对象,需要在web.xml中配置
User.java(上面的那段代码)
配置web.xml
<!-- 非感知型监听器配置 -->
<listener>
<listener-class>com.r.pojo.User</listener-class>
</listener>
二者的区别
HttpSessionListener只需要设置到web.xml就可以监听整个应用中的所有session
HttpSessionBindingListener必须实例化后放入某一个session中,才能监听
监听范围
- HttpSessionListener设置一次就可以监听所有session
- HttpSessionBindingListener通常是一对一
感知型监听器无需配置,需要和session绑定
非感知型监听器需要在web.xml中配置
MVC设计模式
JSP Model
- 视图(View)- JSP、HTML等:负责与用户交互
- 控制器(Controller)- Servlet:负责流程控制
- 模型(Model)- JavaBean:负责业务逻辑处理、数据库访问
MVC 优点
- 多视图共享一个模型,大大提高代码的可重用性
- MVC三个模块相互独立,松耦合架构
- 控制器提高了应用程序的灵活性和可配置性
- 有利于软件工程化管理
- 完美的系统架构 = 松耦合 + 高重用性 + 高扩展性
MVC 缺点
- 原理复杂
- 增加了系统结构和实现的复杂性
- 视图对模型数据的低效率访问