Spring中过滤器(Filter)及监听器(Listener)的使用

Filter

1、概述

概念: Filter也称之为过滤器,它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理。使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。
功能: 在HttpServletRequest到达 Servlet 之前,拦截客户的HttpServletRequest 。根据需要检查HttpServletRequest,也可以修改HttpServletRequest 头和数据。

在HttpServletResponse到达客户端之前,拦截HttpServletResponse 。根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。
Filter链: 在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。
web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。
Filter生命周期:

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

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;//拦截请求
这个方法完成实际的过滤操作。当客户请求访问与过滤器关联的URL的时候,Servlet过滤器将先执行doFilter方法。FilterChain参数用于访问后续过滤器。

public void destroy();//销毁
Filter对象创建后会驻留在内存,当web应用移除或服务器停止时才销毁。在Web容器卸载 Filter 对象之前被调用。该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源。

FilterConfig接口:
用户在配置filter时,可以使用为filter配置一些初始化参数,当web容器实例化Filter对象,调用其init方法时,会把封装了filter初始化参数的filterConfig对象传递进来。因此开发人员在编写filter时,通过filterConfig对象的方法,就可获得以下内容:

String getFilterName();//得到filter的名称。 
String getInitParameter(String name);//返回在部署描述中指定名称的初始化参数的值。如果不存在返回null. 
Enumeration getInitParameterNames();//返回过滤器的所有初始化参数的名字的枚举集合。 
public ServletContext getServletContext();//返回Servlet上下文对象的引用。

2、Filter使用示例

Filter实现类

package com.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class myFilter implements Filter {
	private FilterConfig config;
	public void init(FilterConfig config) {
		this.config = config;
	}
	public void destory() {
		this.config=null;
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		ServletContext context = this.config.getServletContext();
		long before = System.currentTimeMillis();
		System.out.println("开始过滤....");
		HttpServletRequest hrequest = (HttpServletRequest)request;
		System.out.println("截获到请求地址:"+hrequest.getServletPath());
		String name = config.getInitParameter("name");
		String age = config.getInitParameter("age");
		System.out.println("获取的姓名:"+name);
		System.out.println("获取的年龄:"+age+"\n");
		chain.doFilter(request, response);
		long after = System.currentTimeMillis();
		System.out.println("过滤结束");
		System.out.println("请求被定为到"+hrequest.getRequestURI()+"所花时间为:"+(after-before));
	}
}

web.xml配置

<filter>
  	<filter-name>log</filter-name>
  	<filter-class>com.filter.myFilter</filter-class>
  	<init-param>
  		<param-name>name</param-name>
  		<param-value>Jack</param-value>
  	</init-param>
  	<init-param>
  		<param-name>age</param-name>
  		<param-value>29</param-value>
  	</init-param>
  </filter>
  <filter-mapping>
  	<filter-name>log</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>

3、SpringBoot注解使用Filter示例

在SpringBootApplication上使用@ServletComponentScan注解,Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册,无需其他代码。
启动类:

//去掉自动配置dataSource
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
@ServletComponentScan
public class TestApplication {
	public static void main(String[] args) {
		SpringApplication.run(TestApplication.class, args);
	}
}

具体实现:

@RestController
@RequestMapping("/test")
public class Test1 {
	@PostMapping("/a")
	public void A() {
		System.out.println("aaa");
	}
}

@WebFilter(urlPatterns = "/*")
class TestFilter implements Filter{
	
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("filter初始化!!!!!!!!!!!!!!!");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("filter拦截!");
	}
	
	@Override
	public void destroy() {
		System.out.println("filter销毁!!!!!!!!!!!!");
	}
}

Listener

1、概述

概念: 监听器用于监听web应用中某些对象、信息的创建、销毁、增加,修改,删除等动作的发生,然后作出相应的响应处理。当范围对象的状态发生变化的时候,服务器自动调用监听器对象中的方法。常用于统计在线人数和在线用户,系统加载时进行信息初始化,统计网站的访问量等等。
分类:
1、按监听的对象划分,可以分为
ServletContext对象监听器
HttpSession对象监听器
ServletRequest对象监听器
2、按监听的事件划分
对象自身的创建和销毁的监听器
对象中属性的创建和消除的监听器
session中的某个对象的状态变化的监听器
功能:
1、ServletContextListener:用于监听Web应用的启动和关闭
2、ServletContextAttributeListener:用于监听ServletRequest(application)范围内属性的改变
3、ServletRequestListener:用于监听用户请求
4、ServletRequestAttributeListener:用于监听ServletRequest(request)范围内属性的改变
5、HttpSessionListener:用于监听session的开始和结束
6、HttpSessionAttributeListener:用于监听HttpSession范围(session)内属性的改变

2、基于SpringBoot使用示例

启动类

//去掉自动配置dataSource
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
@ServletComponentScan
public class TestApplication {
	public static void main(String[] args) {
		SpringApplication.run(TestApplication.class, args);
	}
}

具体实现

@RestController
@RequestMapping("/test")
public class Test1 {
	@PostMapping("/a")
	public void A() {
		System.out.println("aaa");
	}
}

@WebListener
class ContextListener implements ServletContextListener{
	@Override
	public void contextInitialized(ServletContextEvent sce) {
		System.out.println("web应用启动了!");
		ServletContextListener.super.contextInitialized(sce);
	}

	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		System.out.println("web应用关闭了!");
		ServletContextListener.super.contextDestroyed(sce);
	}
}

@WebListener
class requestListener implements ServletRequestListener{

	@Override
	public void requestDestroyed(ServletRequestEvent sre) {
		System.out.println("用户请求完成!");
		ServletRequestListener.super.requestDestroyed(sre);
	}

	@Override
	public void requestInitialized(ServletRequestEvent sre) {
		System.out.println("收到用户请求!");
		ServletRequestListener.super.requestInitialized(sre);
	}
	
}

Interceptor

1、概述

1、概念
java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action执行前阻止其执行,同时也提供了一种可以提取Action中可重用部分代码的方式。在AOP中,拦截器用于在某个方法或者字段被访问之前,进行拦截然后再之前或者之后加入某些操作。目前,我们需要掌握的主要是Spring的拦截器,Struts2的拦截器不用深究,知道即可。
2、自定义拦截器的步骤
第一步:自定义一个实现了Interceptor接口的类,或者继承抽象类AbstractInterceptor。
第二步:在配置文件中注册定义的拦截器。
第三步:在需要使用Action中引用上述定义的拦截器,为了方便也可以将拦截器定义为默认的拦截器,这样在不加特殊说明的情况下,所有的
Action都被这个拦截器拦截。
3、过滤器与拦截器的区别
过滤器可以简单的理解为“取你所想取”,过滤器关注的是web请求;拦截器可以简单的理解为“拒你所想拒”,拦截器关注的是方法调用,比如拦截敏感词汇。
3.1,拦截器是基于java反射机制来实现的,而过滤器是基于函数回调来实现的。(有人说,拦截器是基于动态代理来实现的)
3.2,拦截器不依赖servlet容器,过滤器依赖于servlet容器。
3.3,拦截器只对Action起作用,过滤器可以对所有请求起作用。
3.4,拦截器可以访问Action上下文和值栈中的对象,过滤器不能。
3.5,在Action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时调用一次。

2、基于SpringBoot示例

启动类

//去掉自动配置dataSource
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
@ServletComponentScan
public class TestApplication {
	public static void main(String[] args) {
		SpringApplication.run(TestApplication.class, args);
	}
}

具体实现

@RestController
@RequestMapping("/test")
public class Test1 {
	@PostMapping("/a")
	public void A() {
		System.out.println("aaa");
	}
}


class InterceptorTest extends HandlerInterceptorAdapter{
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("preHandle");
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("postHandle");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("afterCompletion");
	}
}

//注册到容器中
@Configuration
class InterceptorConfig implements WebMvcConfigurer{
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(new InterceptorTest()).addPathPatterns("/**");
	}
	
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值