📜  Servlet过滤器(1)

📅  最后修改于: 2023-12-03 15:34:57.087000             🧑  作者: Mango

Servlet过滤器

Servlet过滤器是Java Web应用程序中的一种组件,用于在HTTP请求和响应期间拦截和处理请求。过滤器可以在请求到达Servlet之前对请求进行预处理,以及在响应返回给客户端之前进行后处理。Servlet容器中包含一系列默认过滤器,以及开发人员可以编写自定义过滤器。

过滤器的作用
  • 验证和认证请求:通过过滤器可以检查请求的来源、计算哈希码或数字签名,并验证用户身份。例如,身份验证过滤器可以检查请求中的cookie,如果请求合法,则返回200 OK响应,否则返回401 Unauthorized响应。
  • 请求参数解析:将请求参数解析为Java对象或从URL请求中提取查询参数。
  • 请求转发:将请求重定向到指定的URL或Servlet。
  • 响应加密:对响应生成哈希或数字签名,以确保客户端接收到的响应数据未被篡改。
  • 日志记录:记录请求和响应的信息以跟踪系统中的事件和流量。
  • 缓存:缓存响应以减少对后端资源的访问。
过滤器的生命周期

每个过滤器都实现了javax.servlet.Filter接口,并具有以下方法:

  • init(FilterConfig):在过滤器被初始化时调用一次。
  • doFilter(ServletRequest, ServletResponse, FilterChain):每次收到请求时都会调用。
  • destroy():在过滤器被卸载时调用一次。

init()方法可以读取启动参数,并在过滤器初始化时执行其他必要的设置。doFilter()方法是过滤器的核心,它接收请求并执行相应的处理代码。在对请求进行处理后,必须调用FilterChain对象上的doFilter()方法以将请求传递到下一个过滤器或目标Servlet。destroy()方法用于释放过滤器所使用的资源。

编写自定义过滤器

编写自定义过滤器的步骤如下:

  1. 实现javax.servlet.Filter接口,并覆盖init()、doFilter()和destroy()方法;
  2. 将过滤器配置在web.xml文件中,定义URL模式和请求优先级;
  3. 为FilterConfig配置参数,这些参数将传递到init()方法中。

下面是一个例子,该例子展示了如何实现一个简单的请求日志记录器过滤器。该过滤器记录每个请求的HTTP方法、URL和处理总时间。

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

@WebFilter(urlPatterns = {"/*"})
public class RequestLoggerFilter implements Filter {
    private FilterConfig filterConfig;

    @Override
    public void init(FilterConfig filterConfig) {
        this.filterConfig = filterConfig;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        long startTime = System.currentTimeMillis();

        chain.doFilter(request, response);

        long elapsedTime = System.currentTimeMillis() - startTime;

        String logMessage = String.format("%s %s (%dms)", request.getMethod(), request.getRequestURI(), elapsedTime);
        filterConfig.getServletContext().log(logMessage);    
    }

    @Override
    public void destroy() {
        // 关闭资源
    }
}

web.xml配置:

<web-app>
    <filter>
        <filter-name>RequestLoggerFilter</filter-name>
        <filter-class>com.example.RequestLoggerFilter</filter-class>
        <init-param>
            <param-name>testParam1</param-name>
            <param-value>testValue1</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>RequestLoggerFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

在上面的示例中,实现了Filter接口,覆盖了doFilter()方法以记录每个传入请求的信息,由于是在拦截请求之后记录,因此在请求到达过滤器之前无法记录请求信息。此外,init()方法中可以通过FilterConfig对象访问web.xml文件中的初始化参数(如上例中的testParam1)。

拓展

过滤器是Java Web应用程序中常见的一种组件,开发人员可以基于filter对请求进行预处理和响应处理。此外,还有许多第三方过滤器库,可以轻松实现身份验证、压缩和缓存等功能。例如:

  • Apache Shiro:一个强大的安全框架,可以用于实现身份验证、用户会话管理、授权等功能。
  • ehcache:一个开源的Java缓存库,可以通过Servlet过滤器将请求响应缓存到内存中,并提高应用程序的性能。
  • Google Guava:一个广泛使用的Java实用程序库,包含了许多缓存和集合操作工具。