Servlet监听器、过滤器与Spring拦截器

Servlet监听器、过滤器与Spring拦截器

一、监听器

Servlet监听器是指这样的实例对象,首先它实现了Servlet规范中定义的某些Listener接口,然后由Servlet容器实例化,并在整个web application生命周期中监听某些事件,对监听到的事件调用相应的方法进行处理。

Servlet监听器主要包括ServletContextListener、HttpSessionListener、ServletRequestListener这三大类监听器。

ServletContextListener   负责监听Servlet上下文(亦即整个web application)的创建/销毁事件

HttpSessionListener   负责监听Session会话的创建/销毁事件

ServletRequestListener   负责监听用户请求的发起/返回事件。

当这些事件发生时,会自动触发已注册的监听器实例来进行相应处理。

Servlet监听器需要在web项目的web.xml文件中注册,或者使用@WebListener注解。

以一个简单例子作为说明:

package com.funway.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class FirstListener implements ServletContextListener {

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        System.out.println("监听到web app销毁");
    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        System.out.println("监听到web app启动");
    }
}
    <listener>
        <listener-class>com.funway.listener.FirstListener</listener-class>
    </listener>

PS: 除了上面的三大类监听器,Servlet API中还定义了其他更细分的监听器,比如HttpSessionActivationListener、ServletContextAttributeListener等等。

 

二、过滤器

Servlet过滤器负责过滤用户对web资源的请求,并在返回Response前做一些自定义的操作。同监听器一样,Servlet过滤器必须要先实现Filter接口,然后在web.xml中注册,并由Servlet容器来实例化。它的生命周期同样是整个web application的运行时。

过滤用户对web资源的请求,这听起来有点像ServletRequestListener监听器的功能,都是捕获请求并执行处理。但二者要处理的事情其实是不同的,监听器监听到Request请求后,要做的处理是与web application相关的Servlet上下文,并不能处理ServletRequest与ServletResponse;而过滤器则正是对用户的请求与返回进行加工处理。

过滤器需要在web项目的web.xml配置文件中注册,或者使用@WebFilter注解。

以一个简单的例子作为说明:

package com.funway.filter;

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.http.HttpServletRequest;

public class FirstFilter implements Filter {

    @Override
    // 随web application的销毁而销毁
    public void destroy() {
        System.out.println("过滤器销毁");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain fc)
            throws IOException, ServletException {
        System.out.println("doFilter start");
        
        // 执行一些处理(在本例中我们打印请求的URL地址即可)
        HttpServletRequest request = (HttpServletRequest)req;
        System.out.println(request.getRequestURL());
        
        // 执行过滤器链中其他过滤器的doFilter方法
        fc.doFilter(req, resp);
        
        System.out.println("doFilter end");
    }

    @Override
    // 随web application的启动而启动
    public void init(FilterConfig arg0) throws ServletException {
        System.out.println("过滤器初始化");
    }

}
    <filter>
        <filter-name>FirstFilter</filter-name>
        <filter-class>com.funway.filter.FirstFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>FirstFilter</filter-name>
        <url-pattern>/home.jsp</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

另外,除了默认的对用户Request请求进行过滤的过滤器外,根据web.xml中定义的过滤器的<dispatcher>,Servlet过滤器还有如下几种类型:

屏幕快照 2016-02-01 下午11.38.37

具体的用法就不细说了。

 

三、拦截器

拦截器的作用有点类似于过滤器,同样都是在整个web application生命周期内捕获用户请求事件,然后进行处理。他们二者之间的区别在于:

  1. 检查spring mvc项目的web.xml配置就可以看到,过滤器<filter>跟<servlet>是同级别的,一个web application可以有一个或者多个servlet来负责处理不同的url mapping,spring mvc的基础DispatcherServlet就是一个servlet,拦截器是定义在DispatcherServlet的上下文中的。所以处理顺序是 用户访问 --> 过滤器 --> DispatcherServlet --> 过滤器 --> 返回
  2. 过滤器的作用范围比拦截器大。

以一个简单地例子作为说明:

package com.funway.firstspringmvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class FirstInterceptor implements HandlerInterceptor {

    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        System.out.println("afterCompletion: 在请求全部结束后执行该方法(即已经返回response给用户之后)");
    }

    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
            throws Exception {
        System.out.println("postHandle: 在请求被控制器处理后执行该方法,然后进入视图");
    }

    @Override
    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
        System.out.println("preHandle: 在请求被控制器处理前执行该方法, 然后进入控制器");
        return true;
    }

}
	<!-- 注册拦截器 -->
	<interceptors>
	   <interceptor>
               <!-- 拦截器映射的URL -->
	       <mapping path="/**"/>
               <exclude-mapping path="/home" />
	       <beans:bean class="com.funway.firstspringmvc.FirstInterceptor"></beans:bean>
	   </interceptor>
	</interceptors>

 

参考:

http://www.imooc.com/learn/271

http://www.imooc.com/learn/213

http://www.imooc.com/learn/498

 

One thought on “Servlet监听器、过滤器与Spring拦截器

Leave a Reply to pp Cancel reply

Your email address will not be published. Required fields are marked *

TOC