Spring Boot微服务项目实战(第2版)学习笔记-第6章过滤器和监听器

本章主要介绍如何在Spring Boot中使用过滤器Filter和监听器Listener。

1.Spring Boot使用过滤器Filter

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,也就是我们说的过滤链,具体如图所示。

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

1.2 过滤器Filter的使用

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

WebFilter(filterName="ayUserFilter", urlPatterns="/*")
public class AyUserFilter implements Filter{

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out. printIn("---->>>init");
	}
	
	@override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterchain) throws IOException, ServletException {
		System.out. printIn( "--------->> doFilter");
		filterChain.doFilter(servletRequest, servletResponsee);
	}
	
	@Override
	public void destroy () {
		System. out. printIn ("---------->> destory")
	}
}
  • @WebFilter:用于将一个类声明为过滤器,该注解将会在应用部署时被容器处理,容器根据具体的属性配置将相应的类部署为过滤器。这样在Web应用中使用监听器时,不需要在web.xml文件中配置监听器的相关描述信息了。该注解的常用属性有:filterName、urlPatterns、value等。filterName属性用于指定过滤器的name,等价于XML配置文件中的标签。urlPatterns属性用于指定一组过滤器的URL匹配模式,等价于XML配置文件中的标签。value属性等价于urlPatterns属性,但是两者不可以同时使用。

AyUserFilter.java类开发完成之后,我们需要在入口类DemoApplication.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。虽然条条大路通罗马,但是希望大家先掌握一种方式,一路走到底,而不是纠结于会有几种写法。

1.3 测试

上节代码开发完成之后,重新启动运行项目时,Web容器会初始化AyUserFilter对象,并调用init方法,可以在Intellij IDEA控制台看到打印信息,如图所示。

在浏览器输入http://localhost:8080/ayUser/test访问应用时,AyUserFilter拦截器会拦截本次的请求,并调用doFilter方法,同时会在控制台打印信息,如图所示。

2.Spring Boot使用监听器Listener

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等。

2.2 监听器Listener的使用

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

@WebListener
public class AyUserListener implements ServletContextListener{
	@override
	public void contextInitialized(ServletContextEvent servletContextEvent){
		System.out.printIn("ServletContext上下文初始化");
	}
	@Override
	public void contextDestroyed(ServletContextEvent servletContextEvent){
		System.out.printIn("ServletContext上下文销毁");
	}
}
  • @WebListener:用于将一个类声明为监听器,该注解将会在应用部署时被容器处理,容器根据具体的属性配置将相应的类部署为监听器。这样在Web应用中使用监听器时,不需要在web.xml文件中配置监听器的相关描述信息。
  • ServletContextListener类:能够监听ServletContext对象的生命周期,实际上就是监听Web应用的生命周期。当Servlet容器启动或终止Web应用时,会触发ServletContextEvent事件,该事件由ServletContextListener类来处理。在ServletContextListener接口中定义了处理ServletContextEvent事件的两个方法:contextInitialized和contextDestroyed。
  • contextInitialized:当Servlet容器启动Web应用时调用该方法。在调用完该方法之后,容器再对Filter初始化,并且对那些在Web应用启动时就需要被初始化的Servlet进行初始化。
  • contextDestroyed:当Servlet容器终止Web应用时调用该方法。在调用该方法之前,容器会销毁所有的Servlet和Filter过滤器。

我们可以在contextInitialized方法中查询所有的用户,利用缓存技术把用户数据存放到缓存中。在第7章中我们会具体讲解如何利用监听器和Redis缓存技术来缓存用户数据,提高系统性能。

2.3 测试

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

3.补充阅读材料

3.1 servlet的本质是什么,它是如何工作的?

servlet的本质是什么,它是如何工作的?
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值