监听器,过滤器,拦截器

             监听器(listener),过滤器(filter),拦截器(interceptor)是在开发过程中应用广泛的工具,对三者的区别以及作用做一个总结。如果发现有问题,欢迎指正,转载请注明出处。

一.执行顺序:  

      在常用的ssm框架中,对于监听器,过滤器是配置在web.xml中,执行顺序为:context-param-->listener-->filter-->servlet.

拦截器是在Spring MVC中配置的,整体的一个servlet请求的执行过程:context-param-->listener-->filter-->servlet-->interceptor

     1.1   详解

                    context-param:就是一些需要初始化的配置,放入context-param中,被监听器监听,然后加载;

                   监听器(listener):对项目起到监听的作用,能监听到包括request(请求域),session(会话域)和applicaiton(应用程序)的初始化和属性的变化;

                   servlet:就是对request和response进行处理的容器,它在filter之后执行。servlet其中的一部分就是controller层(标记为servlet_2),还包括渲染视图层(标记为servlet_3)和进入controller之前系统的一些处理部分(servlet_1),另外我们把servlet开始的时刻标记为servlet_0,servlet结束的时刻标记为servlet_4。

                   过滤器(filter):对请求起到过滤的作用,它在监听器之后,作用在servlet之前,对请求进行过滤;

                   拦截器(interceptor):就是对请求和返回进行拦截,它作用在servlet的内部,具体来说有三个地方:

                          1)servlet_1和servlet_2之间,即请求还没有到controller层

                          2)servlet_2和servlet_3之间,即请求走出controller层次,还没有到渲染时图层

                          3)servlet_3和servlet_4之间,即结束视图渲染,但是还没有到servlet的结束

     1.2   三者之间的关系:

拦截器Introspectoraop的一种实现

依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。

在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用

 

只能对controller请求进行拦截,对直接访问静态资源的请求则没办法进行拦截处理

org.springframework.web.

servlet.HandlerInterceptor

过滤器Filter特殊的Servlet

Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。

 

在过滤器中修改字符编码;

在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等

javax.servlet.Filter
监听器Listener系统级    
1)监听 Session、request、context 的创建于销毁,分别为  
HttpSessionLister、ServletContextListener、ServletRequestListener
2)监听对象属性变化,分别为:
HttpSessionAttributeLister、ServletContextAttributeListener、ServletRequestAttributeListener
avax.servlet.ServletContextListener

   

 1.3   使用原则

            1):当需要监听到项目中的一些信息,并且不需要对流程做更改时,用监听器;

            2):当需要过滤掉其中的部分信息,只留一部分时,就用过滤器;

            3):当需要对其流程进行更改,做相关的记录时用拦截器。

二.应用

     2.1   监听器

                      1):监听器Listene:实现了javax.servlet.ServletContextListener 接口的服务器端程序,随web应 用的启动而启                                    动,只 初始化一次,随web应用的停止而销毁。                                                                                                                                      在javax.servlet.ServletContextListener接口中定义了2种方法:                                                                                                                      void contextInitialized(ServletContextEvent sce) 监听器的初始化                                                                                                    void contextDestroyed(ServletContextEvent sce) 监听器销毁                                                                            2):主要作用是:初始化的内容添加工作、设置一些基本的内容、比如一些参数或固定的对象等等。
                      3):应用:例如监听器对数据库连接池DataSource的初始化

        2.1.1   配置:

                      1): 在web.xml中加入以下配置项,自动装配(监听)ApplicationContext.xml的配置信息

   <!-- 以下为配置项:配置之后在web应用中就可以通过ServletContext取得BasicDataSource对象-->
    <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

                      2):也可以加入自定义监听器,在容器启动时设置一些基本的内容、比如一些参数或固定的对象

       创建监听器工具类,实现javax.servlet.ServletContextListener接口,重写contextInitialized与contextDestroyed两个方法

package ssm.listener;

import java.text.MessageFormat;

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

public class MyServletContextListener implements ServletContextListener {

	/**
	 * 执行初始化操作
	 * 当servlet容器初始化完成后便会调用此方法。
	 * 用处:比如创建数据库连接
	 */
	@Override
	public void contextInitialized(ServletContextEvent arg0) {
		
		// 获取ServletContext的实例。
		ServletContext servletContext = arg0.getServletContext();
		
		//初始化参数
		servletContext.setAttribute("name", "张三");
		Object attribute = servletContext.getAttribute("name");
		System.out.println("attribute:  "+attribute);
	}

	/**
	 * 执行初始化操作
	 * 当应用程序从服务器取消部署时被调用。
	 */
	@Override
	public void contextDestroyed(ServletContextEvent arg0) {
		/**
		 * eclipse或myeclipse来开启和关闭tomcat,控制台是不显示内容的,
		 * 在tomcat的安装目录下,使用开启或关闭tomcat命令,可以看到走了contextDestroyed方法。
		 */
		 System.out.println("关闭服务");
		
	}

}

       在web.xml中将注册自定义监听器

   <!-- 以下为配置项:配置之后在web应用中就可以通过ServletContext取得BasicDataSource对象-->
    <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

   <!-- 以下配置项:自定义监听器-->
     <listener>
      <listener-class>ssm.listener.MyServletContextListener</listener-class>
    </listener>

     2.2   过滤器

                      1):过滤器Filter:实现了javax.servlet.Filter 接口的服务器端程序,随web应 用的启动而启动,只 初始化一次,                                  随web应用的停止而销毁。                                                                                                                                                                          在javax.servlet.Filter接口中定义了3个方法:                                                                                                                                        void init(FilterConfig filterConfig)           用于完成过滤器的初始化                                                                                                      void destroy()                               用于过滤器销毁前,完成某些资源的回收                                                                                      void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) 实现过滤功                                                           能,该方法对每个请求增加额外的处理

                      2):主要作用是:过滤字符编码、做一些业务逻辑判断等。
                      3):应用:在web.xml文件配置好要过滤的客户端请求,它都会拦截到请求,此时可以对请求或响应(Request、                                              Response)统一设置编码,简化操作;同时还可以进行逻辑判断,如用户是否已经登录、有没有权限                                              访问该页面等等。

        2.2.1  配置:

           在web.xml中加入以下配置项

 <!-- 解决post乱码问题的过滤器 -->
  <!-- post乱码问题的过滤器,拦截post请求并编码为utf8 -->
  <filter>
      <filter-name>CharacterEncodingFilter</filter-name>
      <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
      <init-param>
          <param-name>encoding</param-name>
          <param-value>utf-8</param-value>
      </init-param>
  </filter>
 <!-- 解决post乱码问题的过滤器 -->
 <!-- 
  	1.由<filter>和 <filter-mapping>组成。<filter-mapping>需要写在后面。 
	2<filter-name> 是自己命名的。注意mapping中的<filter-name>需要和filter中的一样。且如果是多个过滤器,name不能重复。 
	3.<filter-class>是自己的类的路径精确到类名。 
	4.<url-pattern>过滤的url 类型,这里是* 意思是所有请求都需要经过这个过滤器。 
	5.如果是多个过滤器,它是按照 <filter-mapping>的顺序运行的。
  -->
 	<filter>
        <filter-name>filter</filter-name>
        <filter-class>ssm.filter.myFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    创建过滤器工具类,实现javax.servlet.Filter 接口,重写init;destroy;doFilter三个方法

package ssm.filter;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

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;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

public class myFilter implements Filter{
	
	private String encoding;
	private FilterConfig Config;  
	 /**
     * 在Filter销毁前,某些资源的回收
     */
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}
	 /**
     *  实现过滤功能,该方法对每个请求增加额外的处理
     */
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
        System.out.println("实现过滤功能,该方法对每个请求增加额外的处理");
        chain.doFilter(request, response); // 放行,转到下一个过滤器
		
	}
	 /**
     * Filter的初始化
     */
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		 System.out.println("Filter的初始化");
		
	}

}

     2.3   拦截器

                      1):拦截器Interceptor:实现了org.springframework.web.servlet.HandlerInterceptor接口,拦截器是在面向切面                                                                   编程中应用的。                                                                                                                                                    在 org.springframework.web.servlet.HandlerInterceptor接口中定义了3个方法:                                                                                                     preHandle              在业务处理器处理请求之前被调用                                                                                                                      afterCompletion                             在业务处理器处理请求完成之后,生成视图之前执行                                                                  afterCompletion  DispatcherServlet         完全处理完请求之后被调用,可用于清理资源

                      2):主要作用是:拦截请求。
                      3):应用:动态代理就是拦截器的简单实现

        2.3.1  配置:

                    拦截器不是在web.xml配置,在springMVC在spring与springMVC整合的配置文件中配置。

        在springmvc.xml中加入以下配置项

<!-- 配置拦截器,可以直接定义拦截所有请求,也可以自定义拦截路径 -->
<mvc:interceptors>
    <!-- 直接定义拦截所有请求 com.ssm.interceptor.IdentityInterceptor 为自定义拦截器包路径
    <bean class="com.ssm.interceptor.IdentityInterceptor"></bean>-->
        <mvc:interceptor>
             <!-- 拦截/user下的所有方法径-->
             <mvc:mapping path="/**"/>
             <!-- 可以选择不拦截登录和添加以及其他的方法,根据情况自己定-->
		     <mvc:exclude-mapping path="/user/login"/>
		     <mvc:exclude-mapping path="/user/add"/>
		     <bean class="ssm.interceptor.IdentityInterceptor"></bean>
        </mvc:interceptor>
        <!-- 
          <mvc:interceptor>配置多个拦截器 </mvc:interceptor>
        -->
    </mvc:interceptors>
<!-- 配置拦截器,可以直接定义拦截所有请求,也可以自定义拦截路径 -->

创建过滤器工具类,实现org.springframework.web.servlet.HandlerInterceptor接口,重写三个方法

package ssm.interceptor;

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

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

public class IdentityInterceptor implements HandlerInterceptor{
	
	// 在业务处理器处理请求之前被调用       
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("1111111111111");
		return true;
	}
	// 在业务处理器处理请求完成之后,生成视图之前执行  
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		
	}
	//完全处理完请求之后被调用,可用于清理资源
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub
		
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值