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

如何在Spring Boot内嵌Jetty中启用CompactPathRule解决路径错误

解决Spring Boot内嵌Jetty的AMBIGUOUS_EMPTY_SEGMENT错误:启用CompactPathRule及相关问题处理

一、启用CompactPathRule的正确配置方式

Spring Boot内嵌Jetty无法通过XML配置,需通过JettyServerCustomizer自定义服务器配置来启用CompactPathRule,具体实现如下:

import org.eclipse.jetty.server.*;
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JettyConfig {

    @Bean
    public JettyServerCustomizer jettyServerCustomizer() {
        return server -> {
            // 遍历所有连接器配置Http规则
            for (Connector connector : server.getConnectors()) {
                HttpConnectionFactory connFac = connector.getConnectionFactory(HttpConnectionFactory.class);
                if (connFac != null) {
                    HttpConfiguration httpConfig = connFac.getHttpConfiguration();
                    // 基于默认合规规则启用CompactPathRule,按需调整规则集
                    UriCompliance uriCompliance = UriCompliance.DEFAULT.withRules(UriCompliance.Rule.COMPACT_PATH);
                    httpConfig.setUriCompliance(uriCompliance);
                }
            }
        };
    }
}

CompactPathRule会自动压缩路径中的连续空段(如//)为单个/,从根源避免AMBIGUOUS_EMPTY_SEGMENT错误。

二、违规监听器不触发的原因

你之前的代码中,通过自定义UriCompliance允许了AMBIGUOUS_EMPTY_SEGMENT违规项,此时Jetty会将该情况判定为“合规”,不会触发违规监听器事件。只有当该违规项被禁止时,监听器才会收到对应事件。

若需监听该违规,需确保自定义UriCompliance不包含允许该违规,或直接使用默认的UriCompliance.DEFAULT(默认禁止AMBIGUOUS_EMPTY_SEGMENT),再添加监听器:

// 示例:使用默认合规规则并监听AMBIGUOUS_EMPTY_SEGMENT违规
connFac.getHttpConfiguration().addComplianceViolationListener(event -> {
    if (event.getViolation() == UriCompliance.Violation.AMBIGUOUS_EMPTY_SEGMENT) {
        System.err.println("检测到AMBIGUOUS_EMPTY_SEGMENT违规");
    }
});

三、URL重写的替代方案

若倾向于通过URL重写处理空路径段,可在Spring Boot中为Jetty添加RewriteHandler,自动修正路径格式:

import org.eclipse.jetty.server.handler.RewriteHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.Rule;

@Bean
public JettyServerCustomizer jettyRewriteCustomizer() {
    return server -> {
        RewriteHandler rewriteHandler = new RewriteHandler();
        // 添加规则:将路径中多个连续/替换为单个/
        rewriteHandler.addRule(new Rule() {
            @Override
            public String apply(String target, Request request) {
                if (target.contains("//")) {
                    String normalizedPath = target.replaceAll("/+", "/");
                    request.setURI(normalizedPath);
                    return normalizedPath;
                }
                return null;
            }
        });
        // 将RewriteHandler加入服务器处理链最前端
        HandlerCollection handlerCollection = new HandlerCollection();
        handlerCollection.setHandlers(new Handler[]{rewriteHandler, server.getHandler()});
        server.setHandler(handlerCollection);
    };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 03:06:11