# 过滤器和监听器
Servlet,Filter和Listener是JavaWeb的三大组件:
- servlet扮演了重要的角色,作为一个中转处理的容器,他连接了客户端和服务器端的信息交互和处理。客户端发送请求,传递到servlet容器,而servlet将数据转换成服务器端可以处理的数据再发送给服务器端,再数据处理之后,再传递到servlet容器,servlet再转译到客户端,完成了一次客户端和服务器端的信息交互。
- filter用于拦截用户请求,在服务器作出响应前,可以在拦截后修改request和response。
- listener通常可以统计在线人数(HttpSessionLisener),加载初始化信息(ServletContextListener),统计网站访问量和实现访问监控。
# 过滤器
Filter(过滤器)用于拦截用户请求,在服务器作出响应前,可以在拦截后修改request和response,一般完成登录验证、统一编码处理、敏感字符过滤等操作。使用过滤器步骤为:
- 定义一个类,实现接口Filter
- 复写方法
- 配置拦截路径:
web.xml:
<filter> <filter-name>filter1</filter-name> <filter-class>SimpleLogin.service.FilterTest</filter-class> </filter> <filter-mapping> <filter-name>filter1</filter-name> <!-- 拦截路径 --> <url-pattern>/*</url-pattern> </filter-mapping>
1
2
3
4
5
6
7
8
9注解:@WebFilter("/*")
# 生命周期
过滤器执行过程为:
- 执行过滤器
- 执行放行后的资源
- 回来执行过滤器放行代码下边的代码
当有多个过滤器时,比如有两个过滤器:过滤器1和过滤器2,它们的执行过程如下:
- 过滤器1
- 过滤器2
- 资源执行
- 过滤器2放行后代码
- 过滤器1放行后代码
那么如何确定过滤器执行先后顺序问题呢?
- 注解配置:按照类名的字符串比较规则比较,值小的先执行,比如AFilter 和 BFilter,就先执行AFilter了。
- web.xml配置: <filter-mapping>谁定义在上边,谁先执行。
Filter类中的方法的声明周期为:
- init:在服务器启动时,会创建Filter对象,然后调用init方法,只执行一次,常用于加载资源。
- doFilter:每一次请求被拦截资源时,就会执行,它能执行多次。
- destroy:如果服务器是正常关闭,则会执行destroy方法,只执行一次,常用于释放资源。
# 拦截配置
关于拦截路径的配置,有四种情况:
- 具体资源路径:/index.jsp 。访问index.jsp资源时,过滤器才会被执行
- 拦截目录: /user/* 。访问/user下的所有资源时,过滤器都会被执行
- 后缀名拦截: *.jsp 。访问所有后缀名为jsp资源时,过滤器都会被执行
- 拦截所有资源:/* 。访问所有资源时,过滤器都会被执行
关于拦截方式的配置,有五种情况:
- REQUEST:默认值。浏览器直接请求资源
- FORWARD:转发访问资源
- INCLUDE:包含访问资源
- ERROR:错误跳转资源
- ASYNC:异步访问资源
有两种方式配置拦截方式:
- 在注解中需要设置dispatcherTypes属性:
@WebFilter(value="/*",dispatcherTypes ={ DispatcherType.FORWARD,DispatcherType.REQUEST})
- 在web.xml中设置<dispatcher></dispatcher>标签即可。
示例为:
package SimpleLogin.service;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
/**
* Servlet Filter implementation class FilterTest
*/
//访问所有资源前访问该过滤器
@WebFilter("/*")
public class FilterTest implements Filter {
/**
* Default constructor.
*/
public FilterTest() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
HttpServletRequest request2 = (HttpServletRequest)request;
System.out.println("filterTest被执行了....访问URL为:"+request2.getRequestURL());
// pass the request along the filter chain
chain.doFilter(request, response);
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# Listener
# 基本概念
监听器实现事件监听机制,监听机制相关概念为:
- 事件:一件事情
- 事件源:事件发生的源头
- 监听器:对事件进行监听的一个对象
- 注册监听:将事件、事件源、监听器绑定在一起。当事件源上发生某个事件后,执行监听器代码
它的作用为:
- 监听web对象创建与销毁
- 监听web对象的属性变化
- 监听session绑定javaBean操作
监听器的创建步骤如下:
- 创建监听器接口
- 重写接口方法
- 配置web.xml
- 测试监听器
# 监听类
Javaweb中常见的监听web对象为HttpServletRequest,HttpSession,ServletContext。
监听web对象的创建于销毁
监听器 监听对象 ServletContextListener ServletContext HttpSessionListener Httpsession ServletRequestListener HttpServletRequest 监听web对象属性的变化
监听器 监听对象 ServletContextAttributeListener ServletContex HttpSessionAttributeListener Httpsession ServletRequestAttributeListener HttpServletRequest 监听session绑定javaBean(向session中set对象的时候触发)
- HttpSessionBindingListener
- HttpSessionActivationListener
# 示例
下面以ServletContextListener为例,来说明监听器的使用,它是用来监听ServletContext对象的创建和销毁。它有两个方法:
- void contextInitialized(ServletContextEvent sce) :ServletContext对象创建后会调用该方法
- void contextDestroyed(ServletContextEvent sce) :ServletContext对象被销毁之前会调用该方法
使用步骤:
- 定义一个类,实现ServletContextListener接口
- 复写方法
- 配置:
web.xml
<listener> <listener-class>cn.itcast.web.listener.ContextLoaderListener</listener-class> </listener>
1
2
3注解:
- @WebListener
示例如下:
在src目录下需要有一个applicationContext文件作为全局配置文件。
配置文件中需要指定初始化参数:
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/classes/applicationContext.xml</param-value> </context-param>
1
2
3
4ListenerTest.java文件内容为:
package SimpleLogin.service; import java.io.FileInputStream; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; /** * Application Lifecycle Listener implementation class ListenerTest * */ @WebListener public class ListenerTest implements ServletContextListener { /** * Default constructor. */ public ListenerTest() { // TODO Auto-generated constructor stub } /** * @see ServletContextListener#contextDestroyed(ServletContextEvent) * 在服务器关闭后,ServletContext对象被销毁。当服务器正常关闭后该方法被调用 */ public void contextDestroyed(ServletContextEvent sce) { // TODO Auto-generated method stub System.out.println("ServletContext对象被销毁了。。。"); } /** * @see ServletContextListener#contextInitialized(ServletContextEvent) * 监听ServletContext对象创建的。ServletContext对象服务器启动后自动创建。 */ public void contextInitialized(ServletContextEvent sce) { // TODO Auto-generated method stub // 加载资源文件 // 1.获取ServletContext对象 ServletContext servletContext = sce.getServletContext(); // 2.加载资源文件 String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation"); // 3.获取真实路径 String realPath = servletContext.getRealPath(contextConfigLocation); // 4.加载进内存 try { FileInputStream fis = new FileInputStream(realPath); System.out.println(fis); } catch (Exception e) { e.printStackTrace(); } System.out.println("ServletContext对象被创建了。。。"); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57