Servlet 过滤器(Filter)是一种用于拦截请求和响应的机制,可以在请求到达Servlet之前或响应返回客户端之前进行预处理或后处理。本文将介绍如何编写和配置Servlet过滤器。


目录

  1. 过滤器概述
  2. 过滤器生命周期
  3. 编写过滤器
  4. 配置过滤器
  5. 完整示例
  6. 部署与测试
  7. 参考资料

1. 过滤器概述

  • 定义:过滤器是Servlet规范的一部分,实现 javax.servlet.Filter 接口。
  • 作用
  • 请求预处理(如认证、日志记录)。
  • 响应后处理(如压缩、编码转换)。
  • 执行顺序:在Servlet之前,按配置顺序执行。

2. 过滤器生命周期

过滤器的生命周期由容器管理,包括以下阶段:

  1. 实例化:容器加载并创建过滤器实例。
  2. 初始化:调用 init(FilterConfig config) 方法。
  3. 过滤:调用 doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 处理请求。
  4. 销毁:调用 destroy() 方法。

3. 编写过滤器

基本结构

过滤器需实现 Filter 接口:

  • init():初始化。
  • doFilter():执行过滤逻辑。
  • destroy():清理资源。

示例:LoggingFilter.java

import java.io.*;
import javax.servlet.*;

public class LoggingFilter implements Filter {
    @Override
    public void init(FilterConfig config) throws ServletException {
        System.out.println("LoggingFilter 初始化");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 请求前处理
        System.out.println("请求到达: " + request.getRemoteAddr());

        // 传递给下一个过滤器或Servlet
        chain.doFilter(request, response);

        // 响应后处理
        System.out.println("响应已发送");
    }

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

4. 配置过滤器

使用 web.xml

<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">
    <filter>
        <filter-name>LoggingFilter</filter-name>
        <filter-class>LoggingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>LoggingFilter</filter-name>
        <url-pattern>/*</url-pattern> <!-- 拦截所有请求 -->
    </filter-mapping>
</web-app>

使用注解(Servlet 3.0+)

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;

@WebFilter(urlPatterns = "/*")
public class LoggingFilter implements Filter {
    // 同上代码
}

5. 完整示例

以下是一个结合Servlet和过滤器的示例。

Servlet:TestServlet.java

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.println("<h1>测试Servlet</h1>");
    }
}

过滤器:AuthFilter.java

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class AuthFilter implements Filter {
    @Override
    public void init(FilterConfig config) throws ServletException {
        System.out.println("AuthFilter 初始化");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        String user = req.getParameter("user");
        if (user != null && user.equals("admin")) {
            chain.doFilter(request, response); // 放行
        } else {
            res.sendError(HttpServletResponse.SC_FORBIDDEN, "未授权访问");
        }
    }

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

配置:web.xml

<web-app>
    <filter>
        <filter-name>AuthFilter</filter-name>
        <filter-class>AuthFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>AuthFilter</filter-name>
        <url-pattern>/test</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>TestServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/test</url-pattern>
    </servlet-mapping>
</web-app>

6. 部署与测试

部署

  1. 编译:
   javac -cp /path/to/tomcat/lib/servlet-api.jar AuthFilter.java TestServlet.java
  1. .class 文件放入 myapp/WEB-INF/classes/
  2. 更新 myapp/WEB-INF/web.xml
  3. 部署 myapp 到Tomcat的 webapps 目录。
  4. 启动Tomcat。

测试

  • 访问:http://localhost:8080/myapp/test?user=admin
  • 输出:<h1>测试Servlet</h1>
  • 访问:http://localhost:8080/myapp/test
  • 输出:403错误,“未授权访问”。

7. 参考资料

出站链接

其他资源

  • 《Head First Servlets and JSP》 – 过滤器章节。
  • X社区:搜索 #ServletFilter 获取示例。

这篇指南展示了如何编写和配置Servlet过滤器。如果需要更复杂的功能(如多个过滤器链或动态配置),请告诉我!