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

Jetty 12实现无效URL转发至错误页:配置及请求头传递问题

Jetty 12迁移后无效URL错误页转发及请求信息保留方案

问题背景

从Jetty 11迁移到Jetty 12后,基于Spring框架的应用中,原JettyEmbeddedErrorHandler(ErrorPageErrorHandler的扩展类)对无效URL的转发行为失效。Jetty 12中无效URL的异常由服务器级错误处理器处理,无法直接与Servlet请求、调度器交互实现转发。使用ReHandlingErrorHandler实现错误页跳转后,原请求的URI、Accept头等关键信息未传递到错误处理器,导致错误页无法根据Accept头返回对应格式的响应。

解决方案

通过自定义ReHandlingErrorHandler子类,重写核心方法保留原请求的Headers和URI信息,实现与Jetty 11一致的转发行为:

1. 自定义ReHandlingErrorHandler子类

重写getReHandlePathInContext保存原URI到请求属性,并重写reHandle方法复制原请求的Headers到重处理请求中:

private static class SilentErrorHandler extends org.eclipse.jetty.server.handler.ReHandlingErrorHandler {
    
    @Override
    protected String getReHandlePathInContext(Request request, int code, Throwable cause) {
        // 将原请求URI存入Servlet标准错误属性,供Spring ErrorController获取
        request.setAttribute("javax.servlet.error.request_uri", request.getRequestURI());
        return "/error";
    }

    @Override
    protected boolean reHandle(Request request, Response response, int code, Throwable cause) {
        // 复制原请求的所有HTTP头信息
        HttpFields originalHeaders = request.getHttpFields();
        
        // 创建重处理请求,复用原请求的通道、服务器信息,复制Headers
        Request reHandleRequest = Request.newRequest(request.getServer(), request.getHttpChannel())
                .setURI(getReHandlePathInContext(request, code, cause))
                .setMethod(request.getMethod()) // 保留原请求方法(如GET/POST)
                .setHttpFields(originalHeaders);

        // 调用父类逻辑执行重处理
        return super.reHandle(reHandleRequest, response, code, cause);
    }

    SilentErrorHandler(Handler handler) {
        super(handler);
        setShowStacks(false);
        setShowMessageInTitle(false);
    }
}

2. 配置Spring JettyServerCustomizer

保持原配置逻辑,将自定义的SilentErrorHandler设置为服务器的错误处理器:

@Bean
public JettyServerCustomizer jettyServerCustomizer(RequestLog requestLog) {
    return server -> {
        server.setErrorHandler(new SilentErrorHandler(server.getHandler()));
        server.setRequestLog(requestLog);
        // 其他服务器配置...
    };
}

3. 错误页处理器适配

在Spring的ErrorController或错误页逻辑中,可通过以下方式获取原请求信息:

  • 原URI:request.getAttribute("javax.servlet.error.request_uri")
  • Accept头:request.getHeader("Accept")

根据Accept头返回对应格式的响应(如HTML/JSON),确保错误页行为符合预期。

原理说明

Jetty 12的ReHandlingErrorHandler默认重处理时会创建新的Request对象,未携带原请求的Headers和URI信息。通过重写reHandle方法,复用原请求的通道并复制Headers,同时将原URI存入标准Servlet错误属性,可让错误处理器完整获取原请求的关键信息,复现Jetty 11中请求转发到错误页的行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 04:09:54