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错误页重定向过程也异常(截图:
)。
尝试过在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,启用它并添加规则即可解决问题:
- 确保项目引入依赖(Maven示例):
<dependency> <groupId>org.tuckey</groupId> <artifactId>urlrewritefilter</artifactId> <version>4.0.4</version> <!-- 可使用最新稳定版 --> </dependency>
- 取消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>
- 在
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
相关产品推荐
相关产品推荐

