如何在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
相关产品推荐
相关产品推荐

