Filter过滤器

JavaWeb学习笔记- Filter

什么是Filter

过滤器是 Servlet 容器中的一个组件,主要负责处理请求和响应,具体来说是负责对请求(HttpServletRequest)进行预处理, 以及对响应(HttpServletResponse)进行后处理,在实现上,基于函数回调,它可以对几乎所有请求进行过滤,所以它是依赖 Servlet 容器的。

执行流程

个Tomcat,如果Tomcat配置了拦截器,则由先拦截器该请求,拦截器可以选择拦截请求或者放行请求,也可以加强请求。(对用户发送的request对象进行加强)

Tomcat调用对应的Servlet处理完请求,返回响应结果时,也要走一遍过滤器,但这次不能拦截了。(你服务器要么不接受请求,既然接受了肯定是因为请求合法啊)

image-20200923144351038

入门案例

创建一个类,实现Filter接口。注意!Filter的重名接口有很多,我们要选择javax.servlet包下的。

image-20200923145100148

重写Filter接口的三个方法,其中doFilter是过滤器的核心方法,init()是过滤器初始化时执行,destroy()过滤器销毁时执行。

public class FilterDemo1 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("filterDemo1 被创建了");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filterDemo1 被执行了!");
    }

    @Override
    public void destroy() {
        System.out.println("filterDemo1 被销毁了");
    }
}

web.xml配置拦截路径。/*表示拦截所有请求

注意,在比较早的版本中,web.xml中filter要写在所有的servlet配置的前面,否则会爆红。

<filter>
    <filter-name>filter1</filter-name>
    <filter-class>com.kaikeba.course06.FilterDemo1</filter-class>
</filter>

<filter-mapping>
    <filter-name>filter1</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

书写一个简单的Servlet,方便查看结果

@WebServlet("/hello")
public class URLDemo1 extends HttpServlet {}

结果:

我们无论发出什么请求,servlet不会执行,输出不存在的界面,也是空白界面。

image-20200923145957013

控制台:

我们每次请求,我们的拦截器都进了拦截因为URL是/*,但是我们缺少放行逻辑。

image-20200923150049222

放行:

拦截器有个重要的步骤是放行,当我们拦截请求是,可以在doFilter()内加一些逻辑判读或者增强操作,然后放行。

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    System.out.println("filterDemo1 被执行了!");
    filterChain.doFilter(servletRequest, servletResponse);
}

控制台:

控制台打印了filterDemo1执行了,然后是servlet执行。

image-20200923150738315

注意以下程序执行结果:

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    System.out.println("filterDemo1 放行!");
    filterChain.doFilter(servletRequest, servletResponse);
    System.out.println("filterDemo1 慢走不送!");
}

结果:

我们看到程序的执行顺序是先放行,然后执行Servlet,最后再执行doFilter()下面的代码逻辑。所以doFilter()上面的代码逻辑是用户发送请求,doFilter()下面的代码逻辑是服务器发送响应结果给用户。

image-20200923150802517

生命周期

初始化init

Filter在Tomcat启动时就创建了

image-20200923144816636

放行doFilter

每一次请求拦截请求时执行,每次都是同一个Filter对象,可以多次执行。

销毁destroy

Filter随着Tomcat服务器的关闭而销毁。

image-20200923151717347

注解配置

和Servlet一样,Filter也支持注解配置。

如果只有一个元数据,urlPatterns可以不写。

urlPatterns可以传入多个,是个String[]数组对象。

@WebFilter(urlPatterns = "/*")
public class FilterDemo1 implements Filter {}

URL路径

  1. 普通方式
  • /hello:访问/hello的资源时,拦截器才执行

  • ``/user/hello`:访问/user/hello的资源时,拦截器才执行

  • /index.jsp:访问index.jsp的资源时,拦截器才执行

    很好理解,我们的URL和请求一一对应,不区分大小写。

  1. 添加通配符
  • /*:拦截所有请求
  • /user/*:拦截/hello下的所有请求
  • *.jsp:拦截任何以.jsp结尾的请求

注意事项:

通配符的优先级是非常低的,所以默认情况下。用户发来一个请求,如果我们不是使用通配符的URL也能处理请求,则通配符是不生效的,但是如果没有一个Servlet可以处理一个请求,则通配符*才会生效的。

特殊情况演示:

  1. 错误方式
  • /*.jsp

image-20200922180014744

  • /*/*

    这种方式会失去匹配功能,也根据浏览器而异,一般情况下,该URL什么都无法接收。

  • /he*

image-20200922180042088

拦截方式的配置

filter 有一个重要的属性叫dispatcherTypes,用来设置拦截资源的方式。

  • **REQUEST:**默认值,表示拦截浏览器的直接请求资源
  • **FORWARD:**表示拦截转发访问的资源
  • **INCLUED:**表示拦截包含访问资源
  • **ERROR:**表示拦截错误资源跳转
  • **ASYNC:**表示拦截异步访问资源

可以在@WebFilter中配置也可以在web.xml配置。

注解配置,拦截转发

@WebFilter(urlPatterns = "/*",dispatcherTypes = DispatcherType.FORWARD)
public class FilterDemo1 implements Filter {

xml配置

<filter>
    <filter-name>filter1</filter-name>
    <filter-class>com.kaikeba.course06.FilterDemo1</filter-class>
    <init-param>
        <param-name>dispatcherTypes</param-name>
        <param-value>FORWARD</param-value>
    </init-param>
</filter>

过滤器链

指配置了多个过滤器,并且过滤器之前有一定的包含关系,比如两个过滤器都是拦截/*请求。

过滤器的先后顺序:

  • 注解配置

比较类名的字符串ASCII

@WebFilter("/*")
public void Filter1() implements Filter{
    ...
}

@WebFilterr("/*")
public void Filter2() implements Filter{
    ...
}

  • web.xml配置

按照配置的先后顺序

filter2先执行,然后执行filter1

<filter>
    <filter-name>filter2</filter-name>
    <filter-class>com.kaikeba.course06.FilterDemo2</filter-class>
</filter>

<filter-mapping>
    <filter-name>filter2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
    <filter-name>filter1</filter-name>
    <filter-class>com.kaikeba.course06.FilterDemo1</filter-class>
</filter>

<filter-mapping>
    <filter-name>filter1</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

过滤器链的执行顺序

如果有两个过滤器,过滤器1,过滤器2。执行顺序:

image-20200923154234248

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值