使用过滤器和监听器

Posted 阿_毅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用过滤器和监听器相关的知识,希望对你有一定的参考价值。

开心一笑

【对于不诚实的男友,要毫不犹豫地把他前任掉,就比如我的前任,明明是个无神论者,非要叫我女神,不能忍!】

新书购买

戳图购买 >>>

6.1 Spring Boot使用过滤器Filter

6.1.1 过滤器Filter介绍

Filter也称之为过滤器,是处于客户端与服务器资源文件之间的一道过滤网。它是Servlet技术中最激动人心的技术之一。WEB开发人员通过Filter技术,对Web服务器管理的所有资源:例如Jsp、Servlet、静态图片文件或静态html文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
Filter接口源码如下:

public interface Filter 
    void init(FilterConfig var1) throws ServletException;
    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws 
    IOException, ServletException;
    void destroy();

Filter的创建和销毁由WEB服务器负责。Web应用程序启动时,Web 服务器将创建Filter 的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作,(Filter对象只会创建一次,init方法也只会执行一次)。开发人员通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。

当客户请求访问与过滤器关联的URL的时候,过滤器将先执行doFilter方法。FilterChain参数用于访问后续过滤器。Filter对象创建后会驻留在内存,当Web应用移除或服务器停止时才销毁。在Web容器卸载 Filter 对象之前destroy被调用。该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源。
Filter可以是有很多个,当一个个Filter组合成起来,就形成了一个FilterChain。也就是我们说的过滤链,具体如图6-1所示。

FilterChain的执行顺序遵循先进后出的原则:当Web客户端发送一个Request请求的时候,这个Request请求会先经过FilterChain,由它利用dofilter()方法调用各个子Filter,至于子filter的执行顺序如何,则看客户端是如何制定规则的。当Request请求被第一个Filter处理之后,又通过dofilte()往下传送,被第二个、第三个… Filter截获处理。当Request请求被所有的Filter处理之后,返回的顺序是从最后一个开始进行返回,直到返回给客户端。

6.1.2 过滤器Filter使用

在Spring Boot中使用Filter过滤器很简单。首先我们在项目my-spring-boot的目录/src/main/java/com.example.demo.filter下新建AyUserFilter.java类,具体代码如下:

/**
 * 过滤器
 * @author Ay
 * @date   2017/11/2.
 */
@WebFilter(filterName = "ayUserFilter", urlPatterns = "/*")
public class AyUserFilter implements Filter

    @Override
    public void init(FilterConfig filterConfig) throws ServletException 
        System.out.println("---------->>> init");
    

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
    FilterChain filterChain) throws IOException, ServletException 
        System.out.println("---------->>> doFilter");
        filterChain.doFilter(servletRequest,servletResponse);
    

    @Override
    public void destroy() 
        System.out.println("---------->>> destory");
    

@WebFilter:用于将一个类声明为过滤器,该注解将会在应用部署时被容器处理,容器根据具体的属性配置将相应的类部署为过滤器。这样我们在Web应用中使用监听器时,不需要在web.xml文件中配置监听器的相关描述信息了。该注解的常用属性有:filterName、urlPatterns、value等。filterName属性用于指定过滤器的name,等价于XML配置文件中的标签。urlPatterns属性用于指定一组过滤器的URL匹配模式,等价于XML配置文件中的标签。value属性等价于urlPatterns属性,但是两者不可以同时使用。
AyUserFilter.java类开发完成之后,我们需要在入口类MySpringBootApplication.java中添加注解@ServletComponentScan,具体代码如下:

@SpringBootApplication
@ServletComponentScan
public class MySpringBootApplication 

	public static void main(String[] args) 
		SpringApplication.run(MySpringBootApplication.class, args);
	

@ServletComponentScan:使用该注解后,Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册,无需其它代码。
事实上,在Spring Boot中添加自己的Servlet、Filter和Listener有两种方法,代码注册和注解自动注册。上面我们已经讲解了如何用注解自动祖册,而代码注册可以通过ServletRegistrationBean、FilterRegistrationBean和ServletListenerRegistrationBean注册Bean。虽然条条大路通罗马,但是我希望大家先掌握一种方式,一路走到底,而不是纠结于回子有几种写法。

6.1.3 测试

6.1.2节代码开发完成之后,重新启动运行my-spring-boot项目时,WEB容器会初始化AyUserFilter对象,并调用init方法,所有可以在Intellij IDEA控制台看到打印信息,如图6-2所示。在浏览器输入http://localhost:8080/ayUser/test访问应用时,AyUserFilter拦截器会拦截本次的请求,并调用doFilter方法,同时会在控制台打印信息,如图6-3所示。

图6-2 初始化调用init方法打印信息 图6-3 拦截调用doFilter方法打印信息

6.2 Spring Boot使用监听器Listener

6.2.1 监听器Listener介绍

监听器也叫Listener,是Servlet的监听器,它可以用于监听Web应用中某些对象、信息的创建、销毁、增加,修改,删除等动作的发生,然后作出相应的响应处理。当范围对象的状态发生变化的时候,服务器自动调用监听器对象中的方法。常用于统计在线人数和在线用户,系统加载时进行信息初始化,统计网站的访问量等等。
根据监听对象,可把监听器分为3类:ServletContext(对应application)、HttpSession(对应session)、ServletRequest(对应request)。Application在整个Web服务中只有一个,在Web服务关闭时销毁。Session对应每个会话,在会话起始时创建,一端关闭会话时销毁。Request对象是客户发送请求时创建的(一同创建的还有Response),用于封装请求数据,在一次请求处理完毕时销毁。
根据监听事件分为:监听对象创建与销毁,如:ServletContextListener、监听对象域中属性的增加和删除,如:HttpSessionListener和ServletRequestListener、监听绑定到Session上的某个对象的状态,如ServletContextAttributeListener,HttpSessionAttributeListener,ServletRequestAttributeListener等。

6.2.2 监听器Listener使用

在Spring Boot中使用Listener监听器和Filter基本一样。首先我们在项目my-spring-boot的目录/src/main/java/com.example.demo.listener下新建AyUserListener.java类,具体代码如下:

/**
 * 描述:监听器
 * @author Ay
 * @date   2017/11/4
 */
@WebListener
public class AyUserListener implements ServletContextListener 

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) 
        System.out.println("ServletContext上下文初始化");
    

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) 
        System.out.println("ServletContext上下文销毁");
    

@WebListener:用于将一个类声明为监听器,该注解将会在应用部署时被容器处理,容器根据具体的属性配置将相应的类部署为监听器。这样我们在Web应用中使用监听器时,不需要在web.xml文件中配置监听器的相关描述信息了。
ServletContextListener类:能够监听ServletContext对象的生命周期,实际上就是监听Web应用的生命周期。当Servlet 容器启动或终止Web应用时,会触发ServletContextEvent 事件,该事件由ServletContextListener类来处理。在ServletContextListener接口中定义了处理ServletContextEvent 事件的两个方法:contextInitialized和contextDestroyed。

  1. contextInitialized:当Servlet容器启动Web 应用时调用该方法。在调用完该方法之后,容器再对Filter 初始化,并且对那些在Web 应用启动时就需要被初始化的Servlet 进行初始化。
  2. contextDestroyed:当Servlet容器终止Web应用时调用该方法。在调用该方法之前,容器会先销毁所有的Servlet和Filter过滤器。
    我们可以在contextInitialized方法中查询所有的用户,利用缓存技术把用户数据存放到缓存中。在第七章中我们会具体讲解如何利用监听器和Redis缓存技术来缓存用户数据,提高系统性能。

6.2.3 测试

6.2.2节代码开发完成之后,重新启动运行my-spring-boot项目时,WEB容器会初始化AyUserListener对象,并调用contextInitialized方法,所有可以在Intellij IDEA控制台看到打印信息,如图6-4所示。当我们销毁容器时候,会调用contextDestroyed方法,并在控制台打印信息。这里需要注意的是,在IDEA开发工具里,直接终止容器或者干掉进程是不会执行销毁方法contextDestroyed。


图6-4 容器启动监听打印信息


读书感悟

来自生物学家道格拉斯·埃姆伦《动物武器》

  • 世间只有两种动物武器,一种是攻击性的,比如尖牙和利爪;一种是防御性的,比如护甲和伪装。不管哪一种,都遵循平衡法则。
  • 武器就是雄性动物展示自己有多么威猛强悍的广告牌。
  • 武器越大,就越需要以威慑的力量不战而胜;反过来,威慑力量的体现也需要武器越大越好。就这样,军备竞赛和威慑行为互相驱动,在螺旋上升的进化之梯上越走越远。
  • 在一个种群中,当只有少数个体垄断了生殖权的时候,剩下的那些雄性必定会千方百计地打破常规。

经典故事

父亲欲对一对孪生兄弟作性格改造,因为其中一个过分乐观,而另一个则过分悲观。一天,他买了许多色泽鲜艳的新玩具给悲观孩子,又把乐观孩子送进了一间堆满马粪的车房里。第二天清晨,父亲看到悲观孩子正泣不成声,便问:为什么不玩那些玩具呢?
“玩了就会坏的。”孩子仍在哭泣。
父亲叹了口气,走进车房,却发现那乐观孩子正兴高采烈地在马粪里掏着什么。
“告诉你,爸爸,”那孩子得意洋洋地向父亲宣称,“我想马粪堆里一定还藏着一匹小马呢!”

【乐观者与悲观者之间,其差别是很有趣的:乐观者看到的是油炸圈饼,悲观者看到的是一个窟窿。】


大神文章


其他

如果有带给你一丝丝小快乐,就让快乐继续传递下去,欢迎鼓励,点赞、顶、欢迎留下宝贵的意见、多谢支持!

以上是关于使用过滤器和监听器的主要内容,如果未能解决你的问题,请参考以下文章

使用过滤器和监听器

基于Springboot搭建java项目(二十三)——SpringBoot使用过滤器拦截器和监听器

拦截器过滤器监听器的区别和使用

Servlet初始配置 监听器和过滤器

Filter过滤和Listener监听器

Filter过滤和Listener监听器