Servlet 过滤器Filter

Servlet 过滤器

Servlet 过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息。

可以将一个或多个 Servlet 过滤器附加到一个 Servlet 或一组 Servlet。Servlet 过滤器也可以附加到 JavaServer Pages (JSP) 文件和 HTML 页面。调用 Servlet 前调用所有附加的 Servlet 过滤器。

Servlet 过滤器是可用于 Servlet 编程的 Java 类,可以实现以下目的:

  • 在客户端的请求访问后端资源之前,拦截这些请求。
  • 在服务器的响应发送回客户端之前,处理这些响应。

Servlet 过滤器方法

过滤器是一个实现了 javax.servlet.Filter 接口的 Java 类。javax.servlet.Filter 接口定义了三个方法:

序号方法 & 描述
1public void doFilter(ServletRequest, ServletResponse, FilterChain) 该方法完成实际的过滤操作,当客户端请求方法与过滤器设置匹配的 URL 时,Servlet 容器将先调用过滤器的 doFilter 方法。FilterChain 用于访问后续过滤器。
2public void init(FilterConfig filterConfig) web 应用程序启动时,web 服务器将创建 Filter 的实例对象,并调用其 init 方法,读取 web.xml 配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(filter 对象只会创建一次,init 方法也只会执行一次)。开发人员通过 init 方法的参数,可获得代表当前 filter 配置信息的 FilterConfig 对象。
3public void destroy() Servlet 容器在销毁过滤器实例前调用该方法,在该方法中释放 Servlet 过滤器占用的资源。

FilterConfig 使用

Filter 的 init 方法中提供了一个 FilterConfig 对象。

web.xml 文件配置如下:

<filter>
    <filter-name>visitfilter</filter-name>
    <filter-class>VisitFilter</filter-class>
    <init-param>
        <param-name>Enable</param-name>
        <param-value>1</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>visitfilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>Code language: HTML, XML (xml)

以上配置表示所有 URL 地址都需要先经过该过滤器,并且配置了一个参数 Enable,在过滤器里面可以获取这个参数的值,达到控制目的。

添加 VisitFilter 类,实现 Filter 接口:

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;

public class VisitFilter implements Filter {

    private FilterConfig config;

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
            throws IOException, ServletException {
        String enable = config.getInitParameter("Enable");
        if ("1".equals(enable)) {
            if (arg0.getParameter("password") != null) {
                // 设置响应内容类型
                arg1.setContentType("text/html;charset=UTF-8");
                arg1.getWriter().append("对不起,系统检测到危险字符。已经屏蔽您的请求。");
                arg1.getWriter().close();
                arg1.getWriter().flush();
            }
        }
        // 把请求传回过滤链
        arg2.doFilter(arg0, arg1);
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        config = arg0;
    }
}Code language: JavaScript (javascript)

当任何 URL 带有 password 参数时,就提示有危险操作,防止有人进行系统攻击。

访问以下地址,只要带上 password 参数就会报该错误:

http://localhost:8080/ServletDemo/home?password=1Code language: JavaScript (javascript)

如果不带 password 参数则正常显示。

注意:过滤的时候如果不希望继续执行后续的输出,记得调用 arg1.getWriter().close()arg1.getWriter().flush()

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注