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

Spring Boot+Jetty升级后自定义Error Handler未生效,求配置方案

如何让自定义Jetty Error Handler在Spring Boot 3.x中优先生效?

问题背景

使用Spring Boot 3.1.10 + Jetty 11.0.20搭建嵌入式Web服务,此前配置的Server级自定义SilentErrorHandler在版本升级后失效。发送无效请求(如curl -H "Content-Type: invalid" http://localhost:8090)时,系统默认使用JettyEmbeddedErrorHandler返回默认错误页面,而非自定义处理器。

核心原因是Jetty的ErrorHandler.getErrorHandler()逻辑:Context级别的Error Handler优先级高于Server级。Spring Boot升级后会自动在Context层面配置JettyEmbeddedErrorHandler,导致Server级的自定义处理器被覆盖。

解决方案

要让自定义Error Handler始终生效,需要同时替换Server级别和所有Context级别的Error Handler。修改WebServerFactoryCustomizer的实现,遍历Jetty Server的Handler树,找到所有ContextHandler并替换其Error Handler:

public class AcmeApiApp implements WebServerFactoryCustomizer<JettyServletWebServerFactory> {
   
    // 其他业务代码...
   
    @Override
    public void customize(JettyServletWebServerFactory factory) {
        SilentErrorHandler customErrorHandler = new SilentErrorHandler();
        
        JettyServerCustomizer serverCustomizer = server -> {
            // 设置Server级别的Error Handler
            server.setErrorHandler(customErrorHandler);
            // 遍历Handler树,替换所有Context级别的Error Handler
            replaceContextErrorHandlers(server.getHandler(), customErrorHandler);
        };
        
        factory.addServerCustomizers(serverCustomizer);
    }

    private void replaceContextErrorHandlers(Handler handler, SilentErrorHandler customErrorHandler) {
        if (handler == null) {
            return;
        }
        
        if (handler instanceof ContextHandler contextHandler) {
            contextHandler.setErrorHandler(customErrorHandler);
        } else if (handler instanceof HandlerCollection handlerCollection) {
            // 处理Handler集合,递归遍历子Handler
            for (Handler childHandler : handlerCollection.getHandlers()) {
                replaceContextErrorHandlers(childHandler, customErrorHandler);
            }
        } else if (handler instanceof HandlerWrapper handlerWrapper) {
            // 处理包装类的Handler,递归获取内部Handler
            replaceContextErrorHandlers(handlerWrapper.getHandler(), customErrorHandler);
        }
    }

    private static final class SilentErrorHandler extends ErrorHandler {
        // 自定义错误处理逻辑实现...
    }

    // 其他业务代码...
}

原理说明

Jetty在处理错误时会优先从当前请求对应的ContextHandler中获取Error Handler,只有当Context级处理器不存在时,才会降级使用Server级的处理器。通过上述代码,我们同时替换了Server和所有Context层面的Error Handler,确保无论错误发生在哪个层级,都会触发自定义的SilentErrorHandler。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 13:26:02