过滤器和拦截器

1.过滤器

1.1 什么是过滤器

请求到达服务端的目标资源(动态,静态)前,先执行一段java程序

Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如 Jsp, Servlet,静态图片文件或静态html 文件等进行拦截,从而实现一些特殊的功能.例如实现URL级别的权限访问控制,过滤敏感词汇,压缩响应信息等一些高级功能.

在这里插入图片描述

1.2 过滤器作用

在HttpServletRequest到达 目标资源(Servlet/jsp,png,css.js) 之前,拦截客户的HttpServletRequest .根据需要检查HttpServletRequest,也可以修改HttpServletRequest 头和数据.


1.3 入门案例
public class MyFirstFilter implements Filter {

    public MyFirstFilter() {
        System.out.println("构造函数被执行了");
    }

    static{
        /*
         * 加载:JVM将硬盘上的MyFirstFilter.class字节码中的内容通过流的方式读取到内存
         */
        System.out.println("字节码正在被加载到内存.....");

    }

    @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("doFilter begin");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("doFilter end");
    }

    @Override
    public void destroy() {
        System.out.println("destroy被执行了");
    }
}

web.xml

<filter>
    <filter-name>MyFilter01</filter-name>
    <filter-class>cn.itcast.filters.MyFilter01</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>MyFilter01</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

注意点:
1.过滤器需要配置在Servlet(DispatherServlet)上,它是先于Servlet执行的,所以我们可以拿到原始的http请求(HttpServletRequest、HpptServletResponse),但我们拿不到请求路径对应的控制器和请求控制器中的方法的信息。(因为通过请求路径找handler是DispatherServlet通过映射器来找的)

思考:如果在过滤器做权限控制?


1.4 过滤器生命周期
  • 服务器启动就创建
  • 当过滤器文件发生改变/服务器正常关闭,会执行destroy方法,销毁过滤器;如果中断服务器,destroy方法没有执行,过滤器会被销毁

Filter的生命周期和WEB应用的生命周期一致ServletContext
在这里插入图片描述


1.5 过滤器执行流程
  1. 服务器tomcat启动的时候读取WEB.XML文件,获取到WEB.XML中所有的<filter-class>标签中的内容.将字节码加载到内存,通过反射调用无参数的构造函数创建各个过滤器对象,执行过滤器上的init方法(仅执行一次)
  2. 每次客户端发请求到服务端的时候,如果当前的过滤器配置的路径和被请求的目标资源的路径匹配,执行过滤器中的doFilter方法,将tomcat创建好的request,response传递给doFilter方法
  3. 执行过滤器中doFilter方法中的代码,如果在执行过程中遇到chain.doFilter(request, response); 相当于放行,tomcat执行本次目标资源,目标资源执行完毕之后,继续执行doFilter方法中放行之后的语句什么是目标资源:如果本次请求的是一个HTML文件,那么目标资源就是这个HTML文件如果本次请求的是一个SERVLET,那么本次的目标资源就是这个SERVLET
  4. 执行过滤器中doFilter方法中的代码,如果在执行过程中没有遇到放行语句Tomcat仅仅是对本次请求响应 HTTP响应部分的响应行,响应头信息
  5. 当发生以下2种情况时,执行过滤器中的destroy方法
    *_项目正常停止,
    *_项目中JAVA源码发生改变,需要重新加载项目

1.6 过滤器链

(1)多个过滤器组合在一起形成过滤器链

(2)为什么要有过滤器链?
过滤器可以实现很多功能,如果把多个功能放在一个过滤器中,不利于项目维护,将不同的功能放在不同的过滤器中实现,这样不需用某个功能的时候,移除其配置即可.当需要某个功能时,单独为其配置一下即可. 过滤器可以当做”可拔插式的组件”,和系统仅仅是在配置文件中耦合

(3)过滤器链执行流程?
在这里插入图片描述

(4)代码
FilterDemo01

public class FilterDemo01 implements Filter {

	public void destroy() {}
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		System.out.println("demo01 11111");
		chain.doFilter(request, response);
		System.out.println("demo01 22222");
	}
	public void init(FilterConfig fConfig) throws ServletException {}
}

FilterDemo02

public class FilterDemo02 implements Filter {
	public void destroy() {}
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		System.out.println("demo02 11111");
		chain.doFilter(request, response);
		System.out.println("demo02 22222");
	}
	public void init(FilterConfig fConfig) throws ServletException {}
}

FilterDemo03

public class FilterDemo03 implements Filter {
	public void destroy() {}
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		System.out.println("demo03 11111");
		chain.doFilter(request, response);
		System.out.println("demo03 22222");
	}
	public void init(FilterConfig fConfig) throws ServletException {}
}

配置文件如下:

<filter>
  <filter-name>FilterDemo01</filter-name>
  <filter-class>cn.itcast.web.filter.FilterDemo01</filter-class>
</filter>
<filter-mapping>
  <filter-name>FilterDemo01</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
  <filter-name>FilterDemo02</filter-name>
  <filter-class>cn.itcast.web.filter.FilterDemo02</filter-class>
</filter>
<filter-mapping>
  <filter-name>FilterDemo02</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
  <filter-name>FilterDemo03</filter-name>
  <filter-class>cn.itcast.web.filter.FilterDemo03</filter-class>
</filter>
<filter-mapping>
  <filter-name>FilterDemo03</filter-name>
  <url-pattern>/*</url-pattern>   
</filter-mapping>

1.7 过滤器的配置

url-pattern的三种配置

  • 完全路径匹配: 以 / 开始
    • /aaa
    • /aaa/bbb
  • 目录匹配: 以 / 开始
    • /*
    • /download/*
  • 扩展名匹配: 不能以 / 开始
    • *.do
    • *.jsp
    • *.action

dispatcher的配置

  • REQUEST:默认值。浏览器直接请求资源,新的请求到来时拦截
  • FORWARD:转发访问资源。只有转发的请求才会拦截。

servlet-name的配置
通过url-pattern拦截一个Servlet的资源.也可以通过servlet-name标签进行拦截.

1.8 运行方式
  • 单实例多线程
  • Servlet能做的事情,过滤器都能做,过滤器更像是横跨在tomcat和目标资源的透明代码,这段代码能否执行取决于是否在配置文件中配置,目标资源是否允许被当前用户请求被调用,取决于过滤器中是否有放行语句
  • 过滤器本质还是一段JAVA小程序,只不过存放的位置不一样,执行的时机不一样,承担的职责也不一样了,美其名曰”过滤器”

2.拦截器

HandlerExecutionChain是一个执行链,当请求到达DispatchServlet时,DispatchServlet根据请求路径到HandlerMapping查询具体的Handler,从HandlerMapping返回给DispatcherServlet,其中包含了一个具体的Handler对象和Interceptors(拦截器集合)。

如何自定义拦截器:

springmvc的拦截器接口(HandlerInterceptor)定义了三个方法:

  • preHandle调用Handler之前执行,称为前置方法
    • 返回值:
      true表示放行,后续业务逻辑继续执行
      false表示被拦截,后续业务逻辑不再执行,但之前返回true的拦截器的完成方法会倒叙执行
  • postHandle调用Handler之后执行,称为后置方法
  • afterCompletion视图渲染完成之后执行

2.1 拦截器的执行过程

在这里插入图片描述
在这里插入图片描述

2.2 编写自定义拦截器

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值