Use Servlet 4 mapping type if available

See gh-25100
This commit is contained in:
Rossen Stoyanchev
2020-05-19 10:30:07 +01:00
parent 23233c3041
commit 5ca7928153
2 changed files with 48 additions and 25 deletions

View File

@@ -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.
* <p>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.
* <p>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 {
}
}