zoukankan      html  css  js  c++  java
  • 过滤器/拦截器/监听器 —— Filter、Interceptor、Listener

    一、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...被打印。

    二、Listener功能

    它是基于观察者模式设计的,Listener 的设计对开发 Servlet 应用程序提供了一种快捷的手段,能够方便的从另一个纵向维度控制程序和数据。目前 Servlet 中提供了 5 种两类事件的观察者接口,它们分别是:

    4 个 EventListeners 类型的,ServletContextAttributeListener、ServletRequestAttributeListener、ServletRequestListener、HttpSessionAttributeListener ;

    2 个 LifecycleListeners 类型的,ServletContextListener、HttpSessionListener。

    Listener是Servlet的监听器,它可以监听客户端的请求、服务端的操作等。通过监听器,可以自动激发一些操作,比如监听在线的用户的数量。

    常用的监听接口有以下几个:

    1、ServletContextAttributeListener监听对ServletContext属性(增/删/改)的操作。

    2、ServletContextListener监听ServletContext的操作:

    • 当创建ServletContext时,激发contextInitialized(ServletContextEvent sce)方法;
    • 当销毁ServletContext时,激发contextDestroyed(ServletContextEvent sce)方法。

    3、HttpSessionListener监听HttpSession的操作:

    • 当创建一个Session时,激发session Created(HttpSessionEvent se)方法(这样就可以给在线人数+1);
    • 当销毁一个Session时,激发sessionDestroyed (HttpSessionEvent se)方法。

    4、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页面:

    <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> 
  • 相关阅读:
    hdu 2647 Reward
    hdu 2094 产生冠军
    hdu 3342 Legal or Not
    hdu 1285 确定比赛名次
    hdu 3006 The Number of set
    hdu 1429 胜利大逃亡(续)
    UVA 146 ID Codes
    UVA 131 The Psychic Poker Player
    洛谷 P2491消防 解题报告
    洛谷 P2587 [ZJOI2008]泡泡堂 解题报告
  • 原文地址:https://www.cnblogs.com/yifanSJ/p/9217365.html
Copyright © 2011-2022 走看看