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

Tomcat 9 URL多斜杠异常问题求助

Tomcat 9 URL多斜杠异常问题解决方案

问题现象

  • 访问http://localhost:8080//Pages/Home.jsp可正常加载页面;
  • 访问不存在的页面http://localhost:8080//Pages/Hoxxxxme.jsp时,可正常重定向到404错误页;
  • 访问http://localhost:8080//Pages//Home.jsp时,页面加载异常(截图:页面加载异常);
  • 访问不存在的http://localhost:8080//Pages/xxx/Home.jsp时,404错误页重定向过程也异常(截图:404重定向异常)。

尝试过在web.xml中配置MIME类型,未解决问题,当前web.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>CredIS</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
<!--   <listener>
    <listener-class>com.crede.system.SessionListener</listener-class>
  </listener>
  <listener>
    <listener-class>com.crede.system.ContextListener</listener-class>
  </listener>

   <filter>
       <filter-name>UrlRewriteFilter</filter-name>
       <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
    </filter>
    <filter-mapping>
       <filter-name>UrlRewriteFilter</filter-name>
       <url-pattern>/*</url-pattern>
    </filter-mapping>
        


 -->  <session-config>
    <session-timeout>32</session-timeout>
  </session-config>
  
 <!-- BLOCK COMMENT FOR TEST LINK. REMOVE COMMENTS FOR PRODUCTION -->
 <!--<security-constraint>
 <web-resource-collection>
 <web-resource-name>Protected Context</web-resource-name>
 <url-pattern>/*</url-pattern>
 </web-resource-collection>
 <user-data-constraint>
 <transport-guarantee>CONFIDENTIAL</transport-guarantee>
 </user-data-constraint>
 </security-constraint> -->
 <!-- BLOCK COMMENT FOR TEST LINK. REMOVE COMMENTS FOR PRODUCTION -->
 </web-app>

解决方案

方法1:修改Tomcat上下文配置强制URL规范化

Tomcat 9默认不会自动处理路径中间的多斜杠,可修改conf/context.xml添加参数,让容器自动规范化URL:

<Context useRelativeRedirects="true" normalizeResourcePath="true">
    <!-- 保留原有配置 -->
</Context>
  • normalizeResourcePath="true":Tomcat会将URL中所有连续多斜杠替换为单个斜杠;
  • useRelativeRedirects="true":重定向时使用相对路径,避免生成带多斜杠的跳转地址。

方法2:启用URLRewriteFilter(推荐)

你的web.xml中已注释了UrlRewriteFilter,启用它并添加规则即可解决问题:

  1. 确保项目引入依赖(Maven示例):
<dependency>
    <groupId>org.tuckey</groupId>
    <artifactId>urlrewritefilter</artifactId>
    <version>4.0.4</version> <!-- 可使用最新稳定版 -->
</dependency>
  1. 取消web.xml中UrlRewriteFilter的注释:
<listener>
    <listener-class>com.crede.system.SessionListener</listener-class>
</listener>
<listener>
    <listener-class>com.crede.system.ContextListener</listener-class>
</listener>

<filter>
    <filter-name>UrlRewriteFilter</filter-name>
    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
  1. 在WEB-INF下创建urlrewrite.xml,添加多斜杠替换规则:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN"
        "http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd">
<urlrewrite>
    <!-- 替换路径中所有连续多斜杠为单个斜杠 -->
    <rule>
        <from>^/(.*?)/{2,}(.*)$</from>
        <to type="redirect">/$1/$2</to>
    </rule>
    <!-- 处理根路径后的多斜杠 -->
    <rule>
        <from>^//(.*)$</from>
        <to type="redirect">/$1</to>
    </rule>
</urlrewrite>

该规则会将所有带多斜杠的URL重定向为规范路径,从根源避免异常。

方法3:自定义Filter处理URL规范化

如果不想引入第三方依赖,可自定义Filter实现多斜杠处理:

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.regex.Pattern;

public class UrlNormalizationFilter implements Filter {
    private static final Pattern MULTI_SLASH_PATTERN = Pattern.compile("/+");

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        
        String requestURI = req.getRequestURI();
        String normalizedURI = MULTI_SLASH_PATTERN.matcher(requestURI).replaceAll("/");
        
        if (!requestURI.equals(normalizedURI)) {
            String queryString = req.getQueryString();
            String redirectUrl = normalizedURI + (queryString != null ? "?" + queryString : "");
            resp.sendRedirect(redirectUrl);
            return;
        }
        
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {}
}

然后在web.xml中注册该Filter:

<filter>
    <filter-name>UrlNormalizationFilter</filter-name>
    <filter-class>com.crede.system.UrlNormalizationFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>UrlNormalizationFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

原因分析

Tomcat 9对URL的解析逻辑中,仅会自动规范化域名后的单个多斜杠(如//Pages/),但路径中间的多斜杠(如/Pages//Home.jsp)不会被默认处理,导致页面加载时静态资源的相对路径计算错误,404重定向时也会基于错误URL生成跳转地址,最终引发异常。

内容的提问来源于stack exchange,提问作者Olcay Çetin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 21:45:32