You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何捕获Http11Processor抛出的HTTP请求头解析错误并记录请求IP

问题描述
  • 运行环境:AWS EC2 实例 + Spring Boot(嵌入式Tomcat)+ Log4J2 日志框架
  • 核心问题:正常请求的访问日志(含请求IP、端点、响应耗时)可通过自定义Log4JAccessValve记录,但请求头/请求行解析失败时,Tomcat的Http11Processor抛出的错误日志默认不包含请求IP,且该异常不会经过AccessLogValve
  • 需求:捕获这类请求解析异常,记录发起请求的客户端IP,用于拦截恶意扫描机器人
解决方案

方法1:自定义Tomcat Error Valve(推荐)

Tomcat的ErrorReportValve负责处理请求生命周期中所有未被捕获的异常,包括Http11Processor阶段的请求解析错误。我们可以通过自定义该Valve来捕获异常并补充IP信息:

1. 实现自定义Error Valve

import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ErrorReportValve;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.servlet.ServletException;
import java.io.IOException;

public class Log4JErrorValve extends ErrorReportValve {
    private static final Logger errorLog = LogManager.getLogger("http_error_log");

    @Override
    protected void report(Request request, Response response, Throwable throwable) {
        // 获取客户端IP地址
        String clientIp = request.getRemoteAddr();
        // 记录包含IP的错误日志
        errorLog.error("请求解析失败,客户端IP: {}", clientIp, throwable);
        // 可选:若不需要Tomcat默认的错误日志输出,可注释下方代码
        super.report(request, response, throwable);
    }
}

2. 在Spring Boot中注册自定义Valve

通过配置TomcatServletWebServerFactory将自定义Valve添加到Tomcat引擎:

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TomcatConfig {
    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() {
        return factory -> {
            factory.addEngineValves(new Log4JErrorValve());
        };
    }
}

方法2:扩展Http11Processor(进阶)

若需要更底层的控制,可通过扩展Http11Processor捕获解析异常,但该方式复杂度较高,仅推荐在特殊场景下使用:

1. 自定义Http11Processor

import org.apache.coyote.http11.Http11Processor;
import org.apache.coyote.Request;
import org.apache.coyote.Response;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;

public class CustomHttp11Processor extends Http11Processor {
    private static final Logger errorLog = LogManager.getLogger("http_error_log");

    public CustomHttp11Processor(org.apache.coyote.ProtocolHandler protocolHandler) {
        super(protocolHandler);
    }

    @Override
    public void service(Request request, Response response) throws IOException {
        try {
            super.service(request, response);
        } catch (IllegalArgumentException | IOException e) {
            // 获取客户端IP
            String clientIp = request.getRemoteAddr();
            errorLog.error("请求解析失败,客户端IP: {}", clientIp, e);
            // 重新抛出异常,保证Tomcat后续错误处理流程正常执行
            throw e;
        }
    }
}

2. 注册自定义Processor

需自定义NioEndpoint替换默认处理器,再配置到Tomcat工厂中,代码相对繁琐,优先推荐方法1。

关键说明
  • AccessLogValve仅处理完成完整请求生命周期的请求,而请求解析失败发生在请求进入Servlet容器之前,因此不会触发该Valve
  • ErrorReportValve是Tomcat处理所有未捕获异常的入口,覆盖请求解析阶段的错误,因此能捕获Http11Processor抛出的异常
  • 记录IP后,可通过AWS WAF或自定义拦截器(如Spring的HandlerInterceptor)实现恶意IP拦截

内容的提问来源于stack exchange,提问作者Maurice

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 13:54:25