JavaWEB-(二十七)过滤器(Filter)

本文最后更新于:May 13, 2023 pm

过滤器(Filter)是处于客户端与服务器目标资源之间的一道过滤技术。Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。

目录

1.过滤器

执行地位在Servlet之前,客户端发生请求时,会先经过Filter,再到达目标Servlet中;响应时,会根据执行流程再次反向执行Filter。
可以解决多个Servlet共性代码的冗余问题(如:乱码处理、登录权限验证)。

2.编写过滤器

Servlet API中提供了一个Filter接口,只需要编写一个Java类实现这个接口即可,而这个类称之为过滤器(Filter)。

步骤:

  1. 编写java类实现Filter接口
  1. 在doFilter方法中编写拦截逻辑。
  1. 设置拦截路径。@WebFilter(value=”/url-pattern”)。这里的url是被拦截的url-pattern。

示例:

被拦截Servlet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.tothefor.filter;

import com.sun.xml.internal.rngom.digested.DOptionalPattern;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
* @Author DragonOne
* @Date 2021/8/22 22:42
*/
@WebServlet(value = "/af")
public class Afilter extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("被拦截资源");
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

过滤器Filter:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.tothefor.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
* @Author DragonOne
* @Date 2021/8/22 22:44
*/
@WebFilter(value = "/af")
public class Bfilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("从这开始");
//将请求向下传递,如果不写,则不会向下执行
filterChain.doFilter(servletRequest,servletResponse);
//响应回来时继续执行,即被拦截的执行完后,继续回来执行的代码
System.out.println("响应回来");
}

@Override
public void destroy() {
}
}

结果:

1
2
3
从这开始
被拦截资源
响应回来

整个过程可以结合第二张示意图进行理解。

3.过滤器配置

在上面是示例中,过滤器的配置使用的是注解的方式。还有一种类似与Servlet的配置:web.xml配置。

1
2
3
4
5
6
7
8
<filter>
<filter-name></filter-name>
<filter-class></filter-class><!--过滤器类全程-->
</filter>
<filter-mapping>
<filter-name></filter-name>
<url-pattern></url-pattern>
</filter-mapping>

具体配置方式,可以参考配置Servlet的web.xml的方式。

3.1 拦截方式

通常有三种形式:

  1. 精准拦截匹配:如:/index.jsp、/myServlet 。
  1. 后缀拦截匹配:如:*.jsp 、*.html 。
  1. 通配符拦截匹配:/* 表示拦截所有。但是需要注意的是过滤器不能使用 / 匹配。

4.过滤器链

客户端对服务器请求之后,服务器调用Servlet之前会执行一组过滤器(多个过滤器),这组过滤器称为一条过滤器链。在一个web应用中,可以编写多个Filter,这些Filter组合起来就是一个Filter链。

当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。如果在doFilter方法中,还调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有Filter,如果有,则调用第二个Filter,如果没有,则调用目标资源。

这种类似于一种递归,递归中是否还有递归,有则先递归,再执行其他的。(一种理解方法)

5.过滤器优先级

    1. 如果为注解的话,是按照类全名称的字符串顺序决定作用顺序。
    1. 如果是web.xml,则按照 filter-mapping 的顺序,从上往下。
    1. web.xml 配置高于注解方式。
    1. 如果注解和 web.xml 同时配置,会创建多个过滤器对象,造成过滤多次。

本文作者: 墨水记忆
本文链接: https://tothefor.com/DragonOne/851885845.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!