diff --git a/spring-web/spring-web.gradle b/spring-web/spring-web.gradle index 0ddcc57f9a1..48599d427a8 100644 --- a/spring-web/spring-web.gradle +++ b/spring-web/spring-web.gradle @@ -8,7 +8,7 @@ dependencies { optional(project(":spring-aop")) optional(project(":spring-context")) optional(project(":spring-oxm")) - optional("javax.servlet:javax.servlet-api:3.1.0") + optional("javax.servlet:javax.servlet-api") // Servlet 4 for mapping type optional("javax.servlet.jsp:javax.servlet.jsp-api") optional("javax.el:javax.el-api") optional("javax.faces:javax.faces-api") diff --git a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java index 5e3ed3b52ee..a3ba76492dd 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java +++ b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java @@ -23,11 +23,13 @@ import java.util.Map; import java.util.Properties; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.MappingMatch; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.lang.Nullable; +import org.springframework.util.ClassUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; @@ -49,6 +51,10 @@ import org.springframework.util.StringUtils; */ public class UrlPathHelper { + private static boolean isServlet4Present = + ClassUtils.isPresent("javax.servlet.http.HttpServletMapping", + UrlPathHelper.class.getClassLoader()); + /** * Special WebSphere request attribute, indicating the original request URI. * Preferable over the standard Servlet 2.4 forward attribute on WebSphere, @@ -154,30 +160,6 @@ public class UrlPathHelper { } - /** - * Return the mapping lookup path for the given request, within the current - * servlet mapping if applicable, else within the web application. - *
Detects include request URL if called within a RequestDispatcher include. - * @param request current HTTP request - * @return the lookup path - * @see #getPathWithinServletMapping - * @see #getPathWithinApplication - */ - public String getLookupPathForRequest(HttpServletRequest request) { - // Always use full path within current servlet context? - if (this.alwaysUseFullPath) { - return getPathWithinApplication(request); - } - // Else, use path within current servlet mapping if applicable - String rest = getPathWithinServletMapping(request); - if (!"".equals(rest)) { - return rest; - } - else { - return getPathWithinApplication(request); - } - } - /** * Variant of {@link #getLookupPathForRequest(HttpServletRequest)} that * automates checking for a previously computed lookupPath saved as a @@ -198,6 +180,40 @@ public class UrlPathHelper { return getLookupPathForRequest(request); } + /** + * Return the mapping lookup path for the given request, within the current + * servlet mapping if applicable, else within the web application. + *
Detects include request URL if called within a RequestDispatcher include. + * @param request current HTTP request + * @return the lookup path + * @see #getPathWithinServletMapping + * @see #getPathWithinApplication + */ + public String getLookupPathForRequest(HttpServletRequest request) { + // Always use full path within current servlet context? + if (this.alwaysUseFullPath || skipServletPathDetermination(request)) { + return getPathWithinApplication(request); + } + // Else, use path within current servlet mapping if applicable + String rest = getPathWithinServletMapping(request); + if (!"".equals(rest)) { + return rest; + } + else { + return getPathWithinApplication(request); + } + } + + private boolean skipServletPathDetermination(HttpServletRequest request) { + if (isServlet4Present) { + if (request.getHttpServletMapping().getMappingMatch() != null) { + return !request.getHttpServletMapping().getMappingMatch().equals(MappingMatch.PATH) || + request.getHttpServletMapping().getPattern().equals("/*"); + } + } + return false; + } + /** * Return the path within the servlet mapping for the given request, * i.e. the part of the request's URL beyond the part that called the servlet, @@ -658,4 +674,11 @@ public class UrlPathHelper { throw new UnsupportedOperationException(); } }; + + + private static class HttpServletMappingHelper { + + + + } }