笔记:
一、过滤器(Filter)
1.概述
过滤器实际上就是对web资源(HTML,CSS,Servlet,JSP)进行拦截,做一些处理后再交给下一个过滤器或Servlet处理
通常都是用来拦截request进行处理的,也可以返回的response进行拦截处理。
2.过滤器使用场景
-
自动登录
-
统一设置编码格式
-
访问权限控制
-
敏感字符过滤等
3.过滤器(Filter)快速入门
(1)编写一个过滤器(Filter),定义类实现口中的抽象方法
(2)在web.xml文件中配置访问过滤路径(和Servlet的配置有些相似)
4.常用配置项
urlPatterns
——以指定资源匹配。列如"/index.jsp"
——以目录匹配。列如"/servlet"
——以 后缀名匹配。列如".jsp"
——通配符,拦截所有web资源。"/*"
5.过滤器(Filter)生命周期
(1)构造器:过滤器(Filter)的构造器在服务器启动时调用。构造器只会调用一次,说明过滤器(FIlter)也是单例多线程的。
(2)init():在构造器被调用后,紧接着被调用。作用:用来初始化过滤器(Filter)
(3)doFiter():每一次拦截请求时都会调用。
(4)destroy方法在项目停止时调用,用来在对象被销毁前做一些收尾工作
6.多个过滤器(Filter)的执行顺序
(1)在web.xml中,filter执行顺序跟<filter-mapping>的顺序有关,先声明的先执行
(2)使用注解配置的话,filter的执行顺序跟名称的字母顺序有关,列如AFiter会比BFilter先执行
(3)如果既有在web.xml中声明的Filter,也有通过注解配置的Filter,那么会优先执行web.xml中配置的Filter
二、监听器(Listener)
1.概述
第三种Servlet程序:监听Servlet Listener
主要功能是负责监听Web的各种操作,当相关的事件触发后将产生事件,并对事件进行处理。
2.分类
监听器分为3种:
-
application监听器
-
session监听器
-
request监听器
事件:点击、移动、键盘、触摸
3.application监听器 Servlet---ServletContext
实现:ServletContextListener(常用)
重写:
//容器启动时调用
public void contextInitialized(ServletContextEvent event){
}
//容器消毁时调用
public void contextDestroyed(ServletContextEvent event){
}
ServletContextEvent事件方法:
.getServletContext() //取得ServletContext对象,即上下文
列如:获取路径问题
event.getServletContext().getContextPath();
4.Session监听器
实现:HTTPSessionListener(偶尔用)
重写:
//session创建时调用
public void sessionCreated(HttpSessionEvent event){
}
//session销毁时调用
public void sessionDestroyed(HttpSessionEvent event){
}
HttpSessionEvent事件方法:
.getSession() //取得当前的session
列如:
event.getSession().getId(); //得到session的ID
实现:HttpSessionAttributeListener(不用,性能差)
重写:
//增加属性时触发
public void attributeAdded(HttpSessionBindingEvent event){
}
//删除属性时触发
public void attributeRemoved(HttpSessionBindingEvent event){
}
//替换属性时触发
public void attributeReplaced(HttpSessionBindingEvent event){
}
HttpSessionBindingEvent事件方法:
.getSession() //取得session
.getName() //取得属性的名称
.getValue() //取得属性的内容
列如:
event.getSession() //取得session
event.getName() //取得属性的名称
event.getValue() //取得属性的内容
5.request监听器
实现:ServletRequestListener(不用,性能差)
重写:
//请求开始时调用
public requestInitialized(ServletRequestEvent event){
}
//请求结束时调用
public requestDestroyed(ServletRequestEvent event){
}
ServletRequestEvent事件方法:
.getServletRequest() //取得ServletRequest对象
.getServletContext() //取得ServletContext对象
例示:
event.getServletRequest().getRemoteAddr(); //得到IP地址
event.getServletContext().getContextPath(); //得到当前路径
为什么说session监听器和request监听器一般都不用?
答:以request监听器为例,如果采用request监听器,那就意味着每次请求都要触发一次监听器,这大大降低了程序的效率,因此很少用。
实现:监听在线人数
分析:创建一个会话就+1,销毁了会话则-1
(在会话被创建时,往全局变量中+1;会话被关闭时,全局变量-1)
服务器停止则移除count
public class AppListrener implements ServletContextListener,HttpSessionListener {
ServletContext app=null;
//容器销毁时调用
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
System.out.println("容器销毁了");
}
//容器初始化时调用
public void contextInitialized(ServletContextEvent sce) {
// TODO Auto-generated method stub
System.out.println("容器初始化了");
app=sce.getServletContext();
Integer count=0;
app.setAttribute("cut", count);
System.out.println(count+"___");
}
//session创建时调用
public void sessionCreated(HttpSessionEvent arg0) {
// TODO Auto-generated method stub
System.out.println("session创建时调用");
Integer count=(Integer)app.getAttribute("cut");
if(count==null){
count=0;
}
count++;
System.out.println("创建时:"+count);
app.setAttribute("cut", count);
}
//session销毁时调用
public void sessionDestroyed(HttpSessionEvent arg0) {
// TODO Auto-generated method stub
System.out.println("session销毁时调用");
Integer count=(Integer)app.getAttribute("cut");
if(count==null){
count=0;
}
count--;
System.out.println("注销时:"+count);
app.setAttribute("cut", count);
}
xml的
web.xml
<listener>
<listener-class>com.servlet.AppListrener</listener-class>
</listener>