首页 > 编程笔记 > Java笔记 阅读:9

Filter是什么,Java Filter过滤器简介(附带实例)

生活中有很多常见的过滤器,如净化水的净水器、保证安全的安检设备、隔绝灰尘或过滤空气的口罩等。过滤器的通用功能就是用来检查,拦截不符合要求的东西。

那么,程序中的过滤器有什么作用呢?程序中的过滤器主要是用来过滤请求,如果请求不满足条件,就不予放行。

Filter 过滤器是 JavaWeb 的三大组件之一,三大组件分别是:Servlet、Filter 过滤器和 Listener 监听器。

Filter简介

过滤器是 JavaWeb 技术中最为实用的技术之一。过滤器是一个实现了特殊接口 Filter 的 Java 类,其作用是对目标资源进行过滤,即实现对 Servlet、JSP、HTML 文件等请求资源的过滤功能。

Filter 是一个运行在服务器上的程序,优先于 Servlet、JSP 或 HTML 文件等请求资源执行。Filter 的工作流程如下图所示:


图 1 Filter 的工作流程

用户通过浏览器发送请求,Filter 先对用户请求进行预处理,然后交给 Servlet 进行处理并生成响应信息,Filter 再对服务器响应进行后续处理,最后将结果返回给浏览器。

可以发现,使用 Filter 有以下几大好处:
Filter 可负责拦截一个或多个请求或响应,一个请求或响应也可以同时被多个 Filter 拦截。多个过滤器组成的链路被称为过滤器链。我们可以通过代码设置多个过滤器的执行顺序,也可以定义不同过滤器的匹配规则。

程序中过滤器常见的应用场景有登录权限检查、解决网站乱码、URL 级别的权限访问控制、过滤敏感字符等。根据功能不同,Filter 可以分为以下几种:

Java Filter入门案例

下面通过案例演示 Filter 的使用,发送一个请求,通过过滤器检查该请求,符合要求才能放行。

过滤器的创建步骤比较简单,具体如下:
创建 FirstServlet,继承 HttpServlet 实现其方法,示例代码如下:
package com.biancheng.servlet;

//省略 import 语句

public class FirstServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("访问到了 FirstServlet...");
    }
}

HTML 页面代码如下。创建超链接,实现单击该超链接跳转 FirstServlet 进行处理:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
    <a href="first">单击请求到 FirstServlet</a>
</body>
</html>

创建过滤器 FirstFilter,实现 Filter 接口,重写 doFilter() 方法,该方法是过滤器核心方法,用于检查过滤。注意不要导错包,Filter 是 javax.servlet 包下的接口。
package com.biancheng.filter;

//注意不要导错包
import javax.servlet.*;
import java.io.IOException;

public class FirstFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    //过滤器核心方法,用于检查过滤
    /*
    * 参数
    * servletRequest 请求
    * servletResponse 响应
    * filterChain 用于放行
    * */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("访问到了 FirstFilter...");
        //放行(看检查结果)
        //原理:依次去寻找下一个过滤器,下一个没有过滤器了,就直接到目标Servlet
        filterChain.doFilter(servletRequest,servletResponse);

        //执行后的代码
        System.out.println("这是 FirstFilter 放行后的代码");
    }

    @Override
    public void destroy() {
    }
}

在 web.xml 文件中配置 FirstServlet 的映射路径,并设置 FirstFilter 的过滤路径:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                             http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--为FirstServlet 设置映射路径-->
    <servlet>
        <servlet-name>FirstServlet</servlet-name>
        <servlet-class>com.biancheng.servlet.FirstServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>FirstServlet</servlet-name>
        <url-pattern>/first</url-pattern>
    </servlet-mapping>
    <!--为FirstFilter 设置过滤路径-->
    <filter>
        <filter-name>abc</filter-name>!--任意值-->
        <filter-class>com.biancheng.filter.FirstFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>abc</filter-name>
        <!--设置过滤路径为/first-->
        <url-pattern>/first</url-pattern>
    </filter-mapping>
</web-app>
从代码中可知,如果 FirstFilter 只想过滤 FirstServlet,那么过滤器的 url-pattern 值必须和 FirstServlet 的 url-pattern 值保持一致。

运行代码,查看后端控制台,如下图所示:


图 2 请求通过过滤器检查过滤

添加过滤器后处理请求的整个流程如下图所示:


图 3 添加过滤器后处理请求的整个流程

客户端向服务器端发送请求,首先经由过滤器检查,符合要求后才会放行,其次进入 Servlet 处理请求,之后依次到达业务层、持久层,以及到达数据库查找需要的数据。响应数据返回客户端的过程,会按原路返回,期间经由 Thymeleaf 渲染后,再次来到过滤器执行“filterChain.doFilter(servletRequest,servletResponse);”放行语句之后的代码,最后将结果返回给客户端。

相关文章