Servlet过滤器(HttpFilter)
Spring拦截器(HttpInterceptor) —— 特定class 或者方法的 filter
Spring AOP —— spring版本的filter
Struts2拦截器(AbstructInterceptor) —— struts版本的filter
Spring 监听器(Listener)
1、Filter的功能
filter功能,它使用户可以改变一个 request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开 servlet时处理response.换种说法,filter其实是一个”servlet chaining”(servlet 链).
一个Filter包括:
1)在servlet被调用之前截获;
2)在servlet被调用之前检查servlet request;
3)根据需要修改request头和request数据;
4)根据需要修改response头和response数据;
5)在servlet被调用之后截获.
服务器每次只调用setFilterConfig方法一次准备filter 的处理;调用doFilter方法多次以处理不同的请求.FilterConfig接口有方法可以找到filter名字及初始化参数信息.服务器可以设置 FilterConfig为空来指明filter已经终结。
每一个filter从doFilter()方法中得到当前的request及response.在这个方法里,可以进行任何的针对request及 response的操作.(包括收集数据,包装数据等).filter调用chain.doFilter()方法把控制权交给下一个filter.一个 filter在doFilter()方法中结束.如果一个filter想停止request处理而获得对response的完全的控制,那它可以不调用下 一个filter
例子:
首先新建一个Filter
- public class LogFilter implements Filter {
- private FilterConfig filterConfig;
- public FilterConfig getFilterConfig() {
- System.err.println("...getFilterConfig...");
- return filterConfig;
- }
- public void setFilterConfig(FilterConfig filterConfig) {
- System.err.println("...setFilterConfig...");
- this.filterConfig = filterConfig;
- }
- @Override
- public void destroy() {
- System.err.println("...filter destroy...");
- }
- @Override
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
- System.err.println("...doFilter...");
- chain.doFilter(request, response);//看到这没,这只要是传递下一个Filter
- }
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- System.err.println("...init Filter...");
- this.filterConfig = filterConfig;
- }
- }
在web.xml里配置
- <filter>
- <filter-name>LogFilter</filter-name>
- <filter-class>com.ee.filter.LogFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>LogFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
启动运行
可以看到...init Filter...首先在TOMCAT启动时即被打印,然后在运行里面再看到...doFilter...被打印。
2、Listener功能
它是基于观察者模式设计的,Listener 的设计对开发 Servlet 应用程序提供了一种快捷的手段,能够方便的从另一个纵向维度控制程序和数据。目前 Servlet 中提供了 5 种两类事件的观察者接口,它们分别是:
4 个 EventListeners 类型的,ServletContextAttributeListener、ServletRequestAttributeListener、ServletRequestListener、HttpSessionAttributeListener ;
2 个 LifecycleListeners 类型的,ServletContextListener、HttpSessionListener。
Listener是Servlet的监听器,它可以监听客户端的请求、服务端的操作等。通过监听器,可以自动激发一些操作,比如监听在线的用户的数量。
常用的监听接口有以下几个:
ServletContextAttributeListener监听对ServletContext属性(增/删/改)的操作。
ServletContextListener监听ServletContext的操作:
当创建ServletContext时,激发contextInitialized(ServletContextEvent sce)方法;
当销毁ServletContext时,激发contextDestroyed(ServletContextEvent sce)方法。
HttpSessionListener监听HttpSession的操作:
当创建一个Session时,激发session Created(HttpSessionEvent se)方法(这样就可以给在线人数+1);
当销毁一个Session时,激发sessionDestroyed (HttpSessionEvent se)方法。
HttpSessionAttributeListener监听HttpSession中的属性的操作。
当在Session增加一个属性时,激发attributeAdded(HttpSessionBindingEvent se) 方法;
当在Session删除一个属性时,激发attributeRemoved(HttpSessionBindingEvent se)方法;
当在Session属性被重新设置时,激发attributeReplaced(HttpSessionBindingEvent se) 方法。
下面我们开发一个具体的例子,这个监听器能够统计在线的人数。在ServletContext初始化和销毁时,在服务器控制台打印对应的信息。当ServletContext里的属性增加、改变、删除时,在服务器控制台打印对应的信息。
要获得以上的功能,监听器必须实现以下3个接口:
HttpSessionListener
ServletContextListener
ServletContextAttributeListener
例子:
- public class OnlineUserListener implements HttpSessionListener,
- ServletContextListener, ServletContextAttributeListener {
- private long onlineUserCount = 0;
- public long getOnlineUserCount() {
- return onlineUserCount;
- }
-
- @Override
- public void attributeAdded(ServletContextAttributeEvent arg0) {
- }
-
- @Override
- public void attributeRemoved(ServletContextAttributeEvent arg0) {
- }
-
- @Override
- public void attributeReplaced(ServletContextAttributeEvent attributeEvent) {
- System.err.println("...attributeReplaced...");
- }
-
- @Override
- public void contextDestroyed(ServletContextEvent arg0) {
- }
-
- @Override
- public void contextInitialized(ServletContextEvent arg0) {
- }
-
- @Override
- public void sessionCreated(HttpSessionEvent httpSessionEvent) {
- onlineUserCount ++;
- toUpdateCount(httpSessionEvent);
- }
-
- @Override
- public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
- onlineUserCount --;
- toUpdateCount(httpSessionEvent);
- }
- private void toUpdateCount(HttpSessionEvent httpSessionEvent){
- httpSessionEvent.getSession().setAttribute("onlineUserCount", onlineUserCount);
- }
- }
Web.xml
- <listener>
- <listener-class>com.ee.listener.OnlineUserListener</listener-class>
- </listener>
JSP页面:
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>主页</title>
- </head>
- <body>
- <h4>你好!</h4>
- 在线人数:<h1><%=request.getSession().getAttribute("onlineUserCount") %></h1>
- </body>
- </html>