过滤器,监听器,拦截器

一、理解它们

看里十几篇博客,总算有点小明白,总的来讲,两张图可以让我看明白点。

通过两幅图我们可以理解拦截器和过滤器的特点

1、过滤器

  过滤器是在请求进入tomcat容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。

理解上面这句话我们就可以知道,进入servlet之前,主要是两个参数:ServletRequest,ServletResponse  那我们得到这两个测试可以干哪些事呢?

我们可以通过ServletRequest得到HttpServletRequest,此时你就可以对请求或响应(Request、Response)那就可以对对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息、字符集统一等一些高级功能。它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理。使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。。它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁。(每次热部署后,都会销毁)。

2、拦截器

从上图我们可以看出过滤器只在servlet前后起作用,所以它既不能捕获异常,获得bean对象等,这些是只能是进入servlet里面的拦截器能过做到。拦截器中用于在某个方法或字段被访问之前,进行拦截然后,在之前或之后加入某些操作。比如日志,安全等。一般拦截器方法都是通过动态代理的方式实现。可以通过它来进行权限验证,或者判断用户是否登陆,或者是像12306 判断当前时间是否是购票时间。

对比一下其实我们可以发现,过滤器能做的事拦截器都能做,二拦截器做的事过滤器不一定做的了。

3、监听器

listener是servlet规范中定义的一种特殊类。用于监听servletContext、HttpSession和servletRequest等域对象的创建和销毁事件。监听域对象的属性发生修改的事件。用于在事件发生前、发生后做一些必要的处理。其主要可用于以下方面:1、统计在线人数和在线用户2、系统启动时加载初始化信息3、统计网站访问量4、记录用户访问路径。

常用的监听器 servletContextListener、httpSessionListener、servletRequestListener)

二、如何创建他们

1、过滤器

自定义Filter 使用Servlet3.0的注解进行配置第三步的@WebFilter就是3.0的注解

1)启动类里面增加 @ServletComponentScan,进行扫描

2)新建一个Filter类,implements Filter,并实现对应的接口

3) @WebFilter 标记一个类为filter,被spring进行扫描

  urlPatterns:拦截规则,支持正则

4)控制chain.doFilter的方法的调用,来实现是否通过放行不放行,web应用resp.sendRedirect("/index.html");场景:权限控制、用户登录(非前端后端分离场景)等

application类

@SpringBootApplication
@ServletComponentScan
public class SpringbootstudyApplication { public static void main(String[] args) {
SpringApplication.run(SpringbootstudyApplication.class, args);
}
}

LoginFilter过滤器

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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper; //过滤器拦截路径
@WebFilter(urlPatterns = "/api/*", filterName = "loginFilter")
public class LoginFilter implements Filter{ /**
* 容器加载的时候调用
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("拦截器进入========拦截器进入========");
} /**
* 请求被拦截的时候进行调用
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("拦截中========拦截中========"); HttpServletRequest hrequest = (HttpServletRequest)servletRequest;
HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) servletResponse);
if(hrequest.getRequestURI().indexOf("/index") != -1 ||
hrequest.getRequestURI().indexOf("/asd") != -1 ||
hrequest.getRequestURI().indexOf("/online") != -1 ||
hrequest.getRequestURI().indexOf("/login") != -1
) {
filterChain.doFilter(servletRequest, servletResponse);
}else {
wrapper.sendRedirect("/login");
} } /**
* 容器被销毁的时候被调用
*/
@Override
public void destroy() {
System.out.println("拦截器销毁========拦截器销毁========");
} }

1、官网地址:https://docs.spring.io/spring-boot/docs/2.1.0.BUILD-SNAPSHOT/reference/htmlsingle/#boot-features-embedded-container-servlets-filters-listeners

二、监听器

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener; @WebListener
public class RequestListener implements ServletRequestListener { @Override
public void requestDestroyed(ServletRequestEvent sre) {
// TODO Auto-generated method stub
System.out.println("======销毁监听器========");
} @Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("======进入监听器========"); }

三、拦截器

CustomWebMvcConfigurer主拦截器需要:

1:添加@Configuration注解

2:实现WebMvcConfigurer接口

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; //主拦截器,根据拦截不同路径跳转不同自定义拦截器 (实现WebMvcConfigurer方法)
@Configuration
public class CustomWebMvcConfigurer implements WebMvcConfigurer { @Override
public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/api1/*/**");
registry.addInterceptor(new TwoIntercepter()).addPathPatterns("/api2/*/**"); //.excludePathPatterns("/api2/xxx/**"); //拦截全部 /*/*/** WebMvcConfigurer.super.addInterceptors(registry);
} }

LoginIntercepter子拦截器

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; public class LoginIntercepter implements HandlerInterceptor{ /**
* 进入controller方法之前
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("LoginIntercepter------->preHandle"); // String token = request.getParameter("access_token");
//
// response.getWriter().print("fail"); return HandlerInterceptor.super.preHandle(request, response, handler);
} /**
* 调用完controller之后,视图渲染之前
*/
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception { System.out.println("LoginIntercepter------->postHandle"); HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
} /**
* 整个完成之后,通常用于资源清理
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("LoginIntercepter------->afterCompletion"); HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
} }

TwoIntercepter同上

github地址:源码

最后总解一下他们:

过滤器:用于属性甄别,对象收集(不可改变过滤对象的属性和行为)

监听器:用于对象监听,行为记录(不可改变监听对象的属性和行为)

拦截器:用于对象拦截,行为干预(可以改变拦截对象的属性和行为)

参考:

1.springboot配置监听器、过滤器和拦截器

2.请教一下关于过滤器,拦截器,监听器具体应用上的区别?

3.springboot过滤器和拦截器的实现和区别

想太多,做太少,中间的落差就是烦恼。想没有烦恼,要么别想,要么多做。上尉【8】

最新文章

  1. jQuery AutoComplete 自动补全
  2. 【HTML5 video】video标签的部分属性解析
  3. selenium获取html的表格单元格数据
  4. flex布局全解析
  5. Adobe Dreamweaver CS6 序列号 注册码(转自91zcm)
  6. org
  7. gcc 编译器
  8. Oracle Dataguard 介绍
  9. Android-FloatingActionButton
  10. HBase API 基础操作
  11. Python3+unittest使用教程
  12. [剑指Offer]10-斐波那契数列(循环)-Java
  13. Day1数据结构和算法
  14. 磁盘性能评价指标—IOPS和吞吐量
  15. 使用 Topshelf 创建 Windows 服务
  16. 前端常用长度单位(px,em,rem,pt)介绍
  17. maven中scope标签详解
  18. 清除 Xcode 项目缓存
  19. Pelican+Github博客搭建详细教程
  20. android httpUrlConnection HttpClient

热门文章

  1. Windows操作系统发展历程
  2. java中的Condition协作线程接口类
  3. SHELL脚本学习-练习写一个脚本4
  4. CENTOS7上安装MYSQL5.7.21流程
  5. 20175316盛茂淞 2018-2019-2 《Java程序设计》第7周学习总结
  6. centos7.6 ssh远程链接配置
  7. Ubuntu修改系统时间
  8. Maths | 病态问题和条件数
  9. C语言编程遇到的问题
  10. node平台的安装与搭建