过滤器(Filter)

1.什么是过滤器?

过滤器是Java Web中的一种预处理/后处理机制,位于客户端与服务器资源之间,可以拦截请求和响应进行统一处理。它是Servlet规范定义的组件,工作在Servlet容器层面。

核心特性

基于责任链模式(Chain of Responsibility)
可配置多个过滤器形成过滤链
不依赖于任何框架(Servlet规范原生支持)

2.过滤器能解决什么问题?

通用预处理

字符编码设置
敏感词过滤
请求参数预处理

安全控制

身份认证与授权
XSS/SQL注入防御
CSRF防护

性能优化

响应压缩(Gzip)
缓存控制
请求限流

日志监控

访问日志记录
请求耗时统计
异常统一捕获

跨域处理

CORS头设置
跨域请求预检处理

3.使用步骤(以Java Web为例)

1. 创建过滤器类(实现javax.servlet.Filter)
public class LoggingFilter implements Filter {
            
    
    @Override
    public void init(FilterConfig filterConfig) {
            
        // 初始化逻辑(通常读取配置参数)
        System.out.println("日志过滤器初始化完成");
    }

    @Override
    public void doFilter(ServletRequest request, 
                        ServletResponse response, 
                        FilterChain chain)
            throws IOException, ServletException {
            
        
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        
        // 1. 预处理(记录请求开始时间)
        long startTime = System.currentTimeMillis();
        System.out.println("收到请求: " + httpRequest.getRequestURI());
        
        // 2. 放行请求(关键操作)
        chain.doFilter(request, response); 
        
        // 3. 后处理(记录响应耗时)
        long duration = System.currentTimeMillis() - startTime;
        System.out.println("请求处理完成,耗时: " + duration + "ms");
    }

    @Override
    public void destroy() {
            
        // 销毁逻辑(释放资源)
        System.out.println("日志过滤器被销毁");
    }
}

2. 注册过滤器(web.xml配置)
<filter>
    <filter-name>loggingFilter</filter-name>
    <filter-class>com.example.LoggingFilter</filter-class>
    <!-- 可配置初始化参数 -->
    <init-param>
        <param-name>logLevel</param-name>
        <param-value>DEBUG</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>loggingFilter</filter-name>
    <!-- URL匹配模式 -->
    <url-pattern>/*</url-pattern>
    <!-- 可指定Servlet名称 -->
    <!-- <servlet-name>servletName</servlet-name> -->
    <!-- 支持Dispatcher类型 -->
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

3. 基于注解的配置(Servlet 3.0+)
@WebFilter(
    urlPatterns = "/*",
    initParams = {
            
        @WebInitParam(name = "logLevel", value = "DEBUG")
    },
    servletNames = {
            "servletName"},
    dispatcherTypes = {
            DispatcherType.REQUEST, DispatcherType.FORWARD}
)
public class LoggingFilter implements Filter {
            
    // ...实现同上
}

4.Spring Boot中的过滤器

1. 创建Spring Bean过滤器
@Component
public class AuthFilter implements Filter {
            
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
            
        
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String token = httpRequest.getHeader("Authorization");
        
        if (!validateToken(token)) {
            
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
            return;
        }
        
        chain.doFilter(request, response);
    }
    
    private boolean validateToken(String token) {
            
        // 实现token验证逻辑
        return true;
    }
}

控制过滤器顺序(实现Ordered接口)

@Component
public class CorsFilter implements Filter, Ordered {
            
    
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
            
        
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with, Authorization");
        
        chain.doFilter(req, res);
    }
    
    @Override
    public int getOrder() {
            
        return Ordered.HIGHEST_PRECEDENCE; // 最高优先级(最先执行)
    }
}

3. 使用FilterRegistrationBean(精确控制)

@Configuration
public class FilterConfig {
            
    
    @Bean
    public FilterRegistrationBean<LoggingFilter> loggingFilter() {
            
        FilterRegistrationBean<LoggingFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new LoggingFilter());
        registration.addUrlPatterns("/*");
        registration.setOrder(Ordered.LOWEST_PRECEDENCE); // 最低优先级
        return registration;
    }
}

5.过滤器最佳实践

职责单一:每个过滤器只处理一个特定功能

性能注意

避免在过滤器中执行耗时操作
合理使用Filter链的短路机制(如认证失败直接return)

异常处理

重定向到错误页面
返回标准错误JSON(针对API请求)

路径匹配策略

<!-- 精确匹配 -->
<url-pattern>/api/users</url-pattern>
<!-- 后缀匹配 -->
<url-pattern>*.jsp</url-pattern>
<!-- 路径匹配 -->
<url-pattern>/admin/*</url-pattern>

常见应用场景实现

// 跨域过滤器
response.setHeader("Access-Control-Allow-Origin", "*");

// 编码过滤器
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");

// XSS防御过滤器
String safeHtml = HtmlUtils.htmlEscape(rawInput);


6.与拦截器(Interceptor)的区别

维度 过滤器(Filter) 拦截器(Interceptor)
规范层级 Servlet规范 Spring框架
执行位置 Servlet容器层面 Spring MVC处理流程中
依赖关系 不依赖任何框架 依赖Spring框架
作用范围 所有请求 仅针对Spring管理的Controller请求
获取上下文 只能获取Servlet API 可获取Spring上下文和处理器方法信息
执行效率 更高效(更底层) 相对稍慢
典型应用 编码设置、全局安全 权限检查、业务日志
© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容