四十九章 — 过滤器和监听器
过滤器 Filter
监听器 Listener
一、掌握过滤器的使用
web三大组件:servlet、过滤器、监听器
1.理解过滤器的特点和执行原理
每次在请求前都要进行一系列编码问题解决和相应格式问题解决
每次请求前需要记录请求日志,响应后也需要记录响应日志
检查当前用户是否有处理目标资源的权限(查看用户是否登录)
过滤器就可以实现上述的简化处理
过滤器
用于拦截传入的请求和传出的响应,监视、修改或以某种方式处理证字啊客户端和服务器之间交换的数据流
过滤器会过滤两次,一次请求过滤,一次响应过滤
在目标资源执行请求处理前进行过滤,在目标资源处理后响应前进行过滤
2.掌握过滤器的创建和配置
File接口: 类似于servlet接口 用于执行过滤操作的接口
FlieConfig接口: 类似于ServletConfig接口 用于获取Filter配置参数信息的接口
- 创建一个类实现过滤器接口
public class HelloFilter1 implements Filter {
@Override
public void destroy() {}
// 执行过滤
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
System.out.println("----->正在执行请求过滤------>");
filterChain.doFilter(request, response); // 放行
System.out.println("----->正在执行响应过滤------>");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
}
- 在web.xml中配置此过滤器
<!-- 配置过滤器 -->
<filter>
<filter-name>helloFilter1</filter-name>
<filter-class>cn.kgc.demo1.HelloFilter1</filter-class>
</filter>
<filter-mapping>
<filter-name>helloFilter1</filter-name>
<!-- http://localhost:8080/newsmgr/xx/xxx?opr=xxx -->
<!-- 过滤器能够给哪些请求进行过滤 (过滤规则) -->
<!-- 此规则同样适用于servlet -->
<!--
完全匹配:
例如:/hello 它只能匹配到 http://localhost:8080/newsmgr/hello
目录匹配:
例如:/hello/*
它能匹配到:http://localhost:8080/newsmgr/hello/test1
它能匹配到:http://localhost:8080/newsmgr/hello/test2/xxx
扩展名匹配:
例如:
*.do
*.action
*.html
它能匹配到:http://localhost:8080/newsmgr/xxx/xxx/xx.do
-->
<url-pattern>/hello/*</url-pattern>
</filter-mapping>
- 还可通过注解配置过滤器
@WebFilter(filterName="helloFilter2",urlPatterns= {"/hello/*"})
public class HelloFilter2 implements Filter {
}
3.Filter的生命周期【面试题】
回顾servlet的生命周期:
当第一次请求过来时,servlet容易会对对应的servlet进行实例化(构造方法)和初始化(init()方法)
每一次请求过来时,服务器都会执行servlet()方法后根据请求方式不同,执行doxx()方法
当服务器正常关闭时会调用servlet的destroy()销毁的动作
File的生命周期:
当服务器启动时,过滤器就会进行实例化(构造方法)和初始化(init()方法)
当情趣符合过滤规则时,会执行doFilter()方法,如果过滤合格,可以选择放行到下一个过滤器(过滤器链),同理响应时也会再次惊醒响应过滤
当服务器正常关闭时,会调用destory()销毁方法
4.理解过滤器链
当多个过滤器的匹配规则都处于交集状态,那么会形成过滤器链,执行完对应的过滤器后,会依次执行后续,最后才执行目标资源(亚的顺序由web.xml中的filter-mapping所决定的的)
5.初始化参数设置
类似于servlet的初始化参数配置
@WebFilter(
filterName="characterEncodingFilter",
urlPatterns= {"/*"},
initParams= {
@WebInitParam(name="encoding",value="UTF-8")
}
)
public class CharacterEncodingFilter implements Filter {
}
二、掌握监听器的使用
1.理解监听器的作用
监听器: 用于监听一些我们特别的作用域对象的活动的一种组件。
ServletContext (application作用域)、HttpSession(session作用域)、ServletRequest(request作用域)三个域对象
2.理解监听器的分类
- 监听作用域创建和销毁的监听器
- ServletContextListener :监听application,恰巧application又是服务器启动时开始
- HttpSessionListener
- ServletRequestListener
- 监听作用域 属性列表的监听器
- ServletContexttAttributeListener
- HttpSessionAttributeListener
- ServletRequestAttributeListener
- 感知型监听器
- HttpSessionBindingListener
- HttpSessionActivationListener
3.掌握监听器的定义和配置
监听作用域创建和销毁的监听器
-
创建一个监听器实现对应的监听接口
public class MyListener2 implements HttpSessionAttributeListener { // 属性添加 @Override public void attributeAdded(HttpSessionBindingEvent sessionBindingEvent) { String name = sessionBindingEvent.getName(); Object value = sessionBindingEvent.getValue(); System.out.println("有属性在添加!"+name+"-->"+value); } // 属性移除 @Override public void attributeRemoved(HttpSessionBindingEvent sessionBindingEvent) { String name = sessionBindingEvent.getName(); Object value = sessionBindingEvent.getValue(); System.out.println("有属性在移除!"+name+"-->"+value); } // 属性替换 @Override public void attributeReplaced(HttpSessionBindingEvent sessionBindingEvent) { String name = sessionBindingEvent.getName(); Object value = sessionBindingEvent.getValue(); System.out.println("有属性在替换!"+name+"-->"+value); } }
监听作用域 属性列表的监听器
- 创建构建一个监听器实习对应的监听器接口
- 在web.xml中配置
<listener>
<listener-class>cn.kgc.demo1.MyListener1</listener-class>
</listener>
感知型监听器
- 在需要感知的类型上去实现对应的接口
- 实现对应的感知方法即可
public class User implements Serializable,HttpSessionBindingListener{
private static final long serialVersionUID = 1L;
private String username;
private String password;
// 省略getter/setter和构造
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
// 当用户类型对象被绑定时触发
// session.setAttribute();
@Override
public void valueBound(HttpSessionBindingEvent event) {
Object value = event.getValue();
User loginUser = (User)value;
System.out.println("用户:"+loginUser.getUsername()+"上线了!");
}
// 当用户类型对象被解绑时触发
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
Object value = event.getValue();
User loginUser = (User)value;
System.out.println("用户:"+loginUser.getUsername()+"下线了!");
}
}