From 5ca79281535fc62f5c2ffc7b432e5322b6e7366e Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 19 May 2020 10:30:07 +0100 Subject: [PATCH] Use Servlet 4 mapping type if available See gh-25100 --- spring-web/spring-web.gradle | 2 +- .../web/util/UrlPathHelper.java | 57 +++++++++++++------ 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/spring-web/spring-web.gradle b/spring-web/spring-web.gradle index 0ddcc57f9a1c..48599d427a80 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 5e3ed3b52eec..a3ba76492dd2 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.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 @@ */ 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,6 +160,26 @@ protected String getDefaultEncoding() { } + /** + * Variant of {@link #getLookupPathForRequest(HttpServletRequest)} that + * automates checking for a previously computed lookupPath saved as a + * request attribute. The attribute is only used for lookup purposes. + * @param request current HTTP request + * @param lookupPathAttributeName the request attribute to check + * @return the lookup path + * @since 5.2 + * @see org.springframework.web.servlet.HandlerMapping#LOOKUP_PATH + */ + public String getLookupPathForRequest(HttpServletRequest request, @Nullable String lookupPathAttributeName) { + if (lookupPathAttributeName != null) { + String result = (String) request.getAttribute(lookupPathAttributeName); + if (result != null) { + return result; + } + } + return getLookupPathForRequest(request); + } + /** * Return the mapping lookup path for the given request, within the current * servlet mapping if applicable, else within the web application. @@ -165,7 +191,7 @@ protected String getDefaultEncoding() { */ public String getLookupPathForRequest(HttpServletRequest request) { // Always use full path within current servlet context? - if (this.alwaysUseFullPath) { + if (this.alwaysUseFullPath || skipServletPathDetermination(request)) { return getPathWithinApplication(request); } // Else, use path within current servlet mapping if applicable @@ -178,24 +204,14 @@ public String getLookupPathForRequest(HttpServletRequest request) { } } - /** - * Variant of {@link #getLookupPathForRequest(HttpServletRequest)} that - * automates checking for a previously computed lookupPath saved as a - * request attribute. The attribute is only used for lookup purposes. - * @param request current HTTP request - * @param lookupPathAttributeName the request attribute to check - * @return the lookup path - * @since 5.2 - * @see org.springframework.web.servlet.HandlerMapping#LOOKUP_PATH - */ - public String getLookupPathForRequest(HttpServletRequest request, @Nullable String lookupPathAttributeName) { - if (lookupPathAttributeName != null) { - String result = (String) request.getAttribute(lookupPathAttributeName); - if (result != null) { - return result; + private boolean skipServletPathDetermination(HttpServletRequest request) { + if (isServlet4Present) { + if (request.getHttpServletMapping().getMappingMatch() != null) { + return !request.getHttpServletMapping().getMappingMatch().equals(MappingMatch.PATH) || + request.getHttpServletMapping().getPattern().equals("/*"); } } - return getLookupPathForRequest(request); + return false; } /** @@ -658,4 +674,11 @@ public void setDefaultEncoding(String defaultEncoding) { throw new UnsupportedOperationException(); } }; + + + private static class HttpServletMappingHelper { + + + + } }