JavaWeb学习笔记——Filter & Listener
@[TOC]
Filter 过滤器
当访问服务器资源的时候,过滤器可以将请求拦截下来,并完成一些特殊的功能,如:登录验证,统一编码处理,敏感字符过滤等
基本使用方法
- 定义一个类来实现
Filter
接口
public class FilterDemo implements Filter
注:实现的Filter
接口应为javax.servlet
下的Filter
- 复写方法
public class FilterDemo implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("FilterDemo1");
// 放行
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
- 配置拦截路径
使用
WebFilter
注解或web.xml
来配置
@WebFilter("/*") // 访问所有资源之前都会执行过滤器
public class FilterDemo implements Filter{
...
}
Filter细节
Filter执行过程
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("Filter Go.....");
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("Filter Come.....");
}
在客户请求资源时,会先经过过滤器,过滤器放行后才可以获取资源,当获取资源之后同样要再一次经过过滤器
以放行方法doFilter()
为界,方法之上的语句都是对request
对象的请求消息增强,方法之下的语句都是对response
对象的响应消息增强
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 对request对象的请求消息增强
System.out.println("Filter Go.....");
// 放行
filterChain.doFilter(servletRequest, servletResponse);
// 对response对象的响应消息增强
System.out.println("Filter Come.....");
}
显示结果为
Filter Go.....
请求资源的输出内容.....
Filter Come.....
Filter的生命周期方法
在服务器启动之后,会创建Filter对象,并调用init()
方法,只执行一次,用于加载资源
每一次请求被拦截资源时,会执行doFilter()
方法,可以执行多次
在服务器关闭后,会销毁Filter对象,若服务器正常关闭,则会调用destory()
方法,只执行一次,用于释放资源
@WebFilter("/*")
public class FilterDemo implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init....");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("doFilter....");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println("destory....");
}
}
启动服务器时控制台输出
init....
doFilter....
请求资源的输出内容....
刷新一次后
init....
doFilter....
请求资源的输出内容....
doFilter....
请求资源的输出内容....
关闭服务器
init....
doFilter....
请求资源的输出内容....
doFilter....
请求资源的输出内容....
destory....
Filter的配置
拦截路径
例 | 描述 | |
---|---|---|
拦截具体资源路径 | /index.jsp | 只有访问指定路径的资源才会执行过滤器 |
拦截目录 | /jsp/* | 访问指定目录下的所有资源都会执行过滤器 |
拦截后缀名 | *.jsp | 访问所有指定后缀的资源都会执行过滤器 |
拦截所有资源 | /* | 访问所有资源时都会执行过滤器 |
拦截方式
给过滤器指定资源被访问的方式,以拦截该访问方式的请求
注解配置
设置
dispatcherTypes
属性
- REQUEST:
默认值
,浏览器直接请求资源 - FORWARD:转发访问资源
- INCLUDE:包含访问资源
- ERROR:错误跳转资源
- ASYNC:异步访问资源
web.xml配置
设置
<dispathcer></dispatcher>
标签
过滤器链
如果存在两个过滤器,分别为F1,F2则过滤器的执行顺序为
F1 -> F2 -> 资源执行 -> F2 -> F1
示例
F1
@WebFilter("/*")
public class F1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("F1 Go...");
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("F1 Come...");
}
@Override
public void destroy() {
}
}
F2
@WebFilter("/*")
public class F2 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("F2 Go...");
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("F2 Come...");
}
@Override
public void destroy() {
}
}
显示结果为
F1 Go...
F2 Go...
访问资源输出...
F2 Come...
F1 Come...
过滤器执行先后顺序问题
注解配置
按照类名进行字符串比较,值较小的先执行
web.xml配置
按照<filter-mapping>
标签的定义顺序执行
Listener 监听器
事件监听机制
-
事件:某些操作
-
事件源:某些组件,即事件发生的位置
-
监听器:一个对象
-
注册监听:将事件,事件源和监听器绑定在一起,当事件源上发生某个事件,则触发监听器
ServletContextListener接口
需要实现的方法
① void contextInitialized(ServletContextEvent servletContextEvent)
ServletContext对象被创建之后调用该方法,可用于加载资源文件
② void contextDestroyed(ServletContextEvent servletContextEvent)
ServletContext对象被销毁之前调用该方法
使用步骤
- 定义一个类来实现ServletContextListener接口
- 实现接口方法
public class ListenerDemo implements ServletContextListener {
// 监听ServletContext对象的创建,服务器启动后自动调用
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("创建ServletContext...");
}
// 监听ServletContext对象的销毁,服务器正常关闭之前调用该方法
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("销毁ServletContext...");
}
}
- 配置Listener
在web.xml
中添加<listener>
标签
<listener>
<listener-class>Listener.ListenerDemo</listener-class>
<!-- listener-class 内填写Listener类的全类名 -->
</listener>
也可以使用@WebListener
注解来配置Listener
评论