summaryrefslogtreecommitdiff
path: root/spring-webmvc/src/main/java/org/springframework/web
diff options
context:
space:
mode:
Diffstat (limited to 'spring-webmvc/src/main/java/org/springframework/web')
-rw-r--r--spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerMapping.java9
-rw-r--r--spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java4
-rw-r--r--spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java1
-rw-r--r--spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java1
-rw-r--r--spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ResponseStatusExceptionResolver.java3
-rw-r--r--spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartMethodArgumentResolver.java10
-rw-r--r--spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java1
-rw-r--r--spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java17
-rw-r--r--spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java103
9 files changed, 93 insertions, 56 deletions
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerMapping.java
index 117bff35..da03f81f 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerMapping.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerMapping.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,6 +54,13 @@ import javax.servlet.http.HttpServletRequest;
public interface HandlerMapping {
/**
+ * Name of the {@link HttpServletRequest} attribute that contains the mapped
+ * handler for the best matching pattern.
+ * @since 4.3.21
+ */
+ String BEST_MATCHING_HANDLER_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingHandler";
+
+ /**
* Name of the {@link HttpServletRequest} attribute that contains the path
* within the handler mapping, in case of a pattern match, or the full
* relevant URI (typically within the DispatcherServlet's mapping) else.
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java
index b401b525..98c33b9d 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java
@@ -132,8 +132,8 @@ public abstract class AbstractHandlerExceptionResolver implements HandlerExcepti
ModelAndView result = doResolveException(request, response, handler, ex);
if (result != null) {
// Print warn message when warn logger is not enabled...
- if (logger.isWarnEnabled() && (this.warnLogger == null || !this.warnLogger.isWarnEnabled())) {
- logger.warn("Resolved [" + ex + "]" + (result.isEmpty() ? "" : " to " + result));
+ if (logger.isDebugEnabled() && (this.warnLogger == null || !this.warnLogger.isWarnEnabled())) {
+ logger.debug("Resolved [" + ex + "]" + (result.isEmpty() ? "" : " to " + result));
}
// warnLogger with full stack trace (requires explicit config)
logException(ex, request);
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java
index f471b36a..3893b2a0 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java
@@ -367,6 +367,7 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
request.getRequestURL() + "': {" + m1 + ", " + m2 + "}");
}
}
+ request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.handlerMethod);
handleMatch(bestMatch.mapping, lookupPath, request);
return bestMatch.handlerMethod;
}
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java
index 16a120cb..48571d6b 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java
@@ -407,6 +407,7 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping i
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
exposePathWithinMapping(this.bestMatchingPattern, this.pathWithinMapping, request);
+ request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, handler);
request.setAttribute(INTROSPECT_TYPE_LEVEL_MAPPING, supportsTypeLevelMappings());
return true;
}
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ResponseStatusExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ResponseStatusExceptionResolver.java
index 80ee3852..cca63932 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ResponseStatusExceptionResolver.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ResponseStatusExceptionResolver.java
@@ -72,8 +72,7 @@ public class ResponseStatusExceptionResolver extends AbstractHandlerExceptionRes
}
}
else if (ex.getCause() instanceof Exception) {
- ex = (Exception) ex.getCause();
- return doResolveException(request, response, handler, ex);
+ return doResolveException(request, response, handler, (Exception) ex.getCause());
}
return null;
}
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartMethodArgumentResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartMethodArgumentResolver.java
index bddd9190..941e47bd 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartMethodArgumentResolver.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartMethodArgumentResolver.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,7 +41,7 @@ import org.springframework.web.multipart.support.RequestPartServletServerHttpReq
/**
* Resolves the following method arguments:
* <ul>
- * <li>Annotated with {@code @RequestPart}
+ * <li>Annotated with @{@link RequestPart}
* <li>Of type {@link MultipartFile} in conjunction with Spring's {@link MultipartResolver} abstraction
* <li>Of type {@code javax.servlet.http.Part} in conjunction with Servlet 3.0 multipart requests
* </ul>
@@ -85,11 +85,13 @@ public class RequestPartMethodArgumentResolver extends AbstractMessageConverterM
/**
- * Supports the following:
+ * Whether the given {@linkplain MethodParameter method parameter} is a multi-part
+ * supported. Supports the following:
* <ul>
* <li>annotated with {@code @RequestPart}
* <li>of type {@link MultipartFile} unless annotated with {@code @RequestParam}
- * <li>of type {@code javax.servlet.http.Part} unless annotated with {@code @RequestParam}
+ * <li>of type {@code javax.servlet.http.Part} unless annotated with
+ * {@code @RequestParam}
* </ul>
*/
@Override
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java
index a92c33a6..22a14efa 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java
@@ -97,6 +97,7 @@ public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionRes
*/
public DefaultHandlerExceptionResolver() {
setOrder(Ordered.LOWEST_PRECEDENCE);
+ setWarnLogCategory(getClass().getName());
}
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java
index 531167c1..d1dee3c9 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java
@@ -641,22 +641,25 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
*/
protected boolean isInvalidPath(String path) {
if (path.contains("WEB-INF") || path.contains("META-INF")) {
- logger.trace("Path contains \"WEB-INF\" or \"META-INF\".");
+ if (logger.isTraceEnabled()) {
+ logger.trace("Path with \"WEB-INF\" or \"META-INF\": [" + path + "]");
+ }
return true;
}
if (path.contains(":/")) {
String relativePath = (path.charAt(0) == '/' ? path.substring(1) : path);
if (ResourceUtils.isUrl(relativePath) || relativePath.startsWith("url:")) {
- logger.trace("Path represents URL or has \"url:\" prefix.");
+ if (logger.isTraceEnabled()) {
+ logger.trace("Path represents URL or has \"url:\" prefix: [" + path + "]");
+ }
return true;
}
}
- if (path.contains("..")) {
- path = StringUtils.cleanPath(path);
- if (path.contains("../")) {
- logger.trace("Path contains \"../\" after call to StringUtils#cleanPath.");
- return true;
+ if (path.contains("..") && StringUtils.cleanPath(path).contains("../")) {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Path contains \"../\" after call to StringUtils#cleanPath: [" + path + "]");
}
+ return true;
}
return false;
}
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java
index d6ca1c33..64dfed2f 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
@@ -34,8 +35,7 @@ import org.springframework.web.util.UrlPathHelper;
/**
* A filter that wraps the {@link HttpServletResponse} and overrides its
* {@link HttpServletResponse#encodeURL(String) encodeURL} method in order to
- * translate internal resource request URLs into public URL paths for external
- * use.
+ * translate internal resource request URLs into public URL paths for external use.
*
* @author Jeremy Grelle
* @author Rossen Stoyanchev
@@ -50,67 +50,52 @@ public class ResourceUrlEncodingFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
- throws IOException, ServletException {
+ throws ServletException, IOException {
+
if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
- throw new ServletException("ResourceUrlEncodingFilter just supports HTTP requests");
+ throw new ServletException("ResourceUrlEncodingFilter only supports HTTP requests");
}
- HttpServletRequest httpRequest = (HttpServletRequest) request;
- HttpServletResponse httpResponse = (HttpServletResponse) response;
- filterChain.doFilter(httpRequest, new ResourceUrlEncodingResponseWrapper(httpRequest, httpResponse));
+ ResourceUrlEncodingRequestWrapper wrappedRequest =
+ new ResourceUrlEncodingRequestWrapper((HttpServletRequest) request);
+ ResourceUrlEncodingResponseWrapper wrappedResponse =
+ new ResourceUrlEncodingResponseWrapper(wrappedRequest, (HttpServletResponse) response);
+ filterChain.doFilter(wrappedRequest, wrappedResponse);
}
- private static class ResourceUrlEncodingResponseWrapper extends HttpServletResponseWrapper {
+ private static class ResourceUrlEncodingRequestWrapper extends HttpServletRequestWrapper {
- private final HttpServletRequest request;
+ private ResourceUrlProvider resourceUrlProvider;
- /* Cache the index and prefix of the path within the DispatcherServlet mapping */
private Integer indexLookupPath;
private String prefixLookupPath;
- public ResourceUrlEncodingResponseWrapper(HttpServletRequest request, HttpServletResponse wrapped) {
- super(wrapped);
- this.request = request;
+ ResourceUrlEncodingRequestWrapper(HttpServletRequest request) {
+ super(request);
}
@Override
- public String encodeURL(String url) {
- ResourceUrlProvider resourceUrlProvider = getResourceUrlProvider();
- if (resourceUrlProvider == null) {
- logger.debug("Request attribute exposing ResourceUrlProvider not found");
- return super.encodeURL(url);
- }
-
- initLookupPath(resourceUrlProvider);
- if (url.startsWith(this.prefixLookupPath)) {
- int suffixIndex = getQueryParamsIndex(url);
- String suffix = url.substring(suffixIndex);
- String lookupPath = url.substring(this.indexLookupPath, suffixIndex);
- lookupPath = resourceUrlProvider.getForLookupPath(lookupPath);
- if (lookupPath != null) {
- return super.encodeURL(this.prefixLookupPath + lookupPath + suffix);
+ public void setAttribute(String name, Object value) {
+ super.setAttribute(name, value);
+ if (ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR.equals(name)) {
+ if (value instanceof ResourceUrlProvider) {
+ initLookupPath((ResourceUrlProvider) value);
}
}
- return super.encodeURL(url);
- }
-
- private ResourceUrlProvider getResourceUrlProvider() {
- return (ResourceUrlProvider) this.request.getAttribute(
- ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR);
}
private void initLookupPath(ResourceUrlProvider urlProvider) {
+ this.resourceUrlProvider = urlProvider;
if (this.indexLookupPath == null) {
- UrlPathHelper pathHelper = urlProvider.getUrlPathHelper();
- String requestUri = pathHelper.getRequestUri(this.request);
- String lookupPath = pathHelper.getLookupPathForRequest(this.request);
+ UrlPathHelper pathHelper = this.resourceUrlProvider.getUrlPathHelper();
+ String requestUri = pathHelper.getRequestUri(this);
+ String lookupPath = pathHelper.getLookupPathForRequest(this);
this.indexLookupPath = requestUri.lastIndexOf(lookupPath);
this.prefixLookupPath = requestUri.substring(0, this.indexLookupPath);
-
if ("/".equals(lookupPath) && !"/".equals(requestUri)) {
- String contextPath = pathHelper.getContextPath(this.request);
+ String contextPath = pathHelper.getContextPath(this);
if (requestUri.equals(contextPath)) {
this.indexLookupPath = requestUri.length();
this.prefixLookupPath = requestUri;
@@ -119,10 +104,48 @@ public class ResourceUrlEncodingFilter extends GenericFilterBean {
}
}
+ public String resolveUrlPath(String url) {
+ if (this.resourceUrlProvider == null) {
+ logger.trace("ResourceUrlProvider not available via request attribute " +
+ "ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR");
+ return null;
+ }
+ if (this.indexLookupPath != null && url.startsWith(this.prefixLookupPath)) {
+ int suffixIndex = getQueryParamsIndex(url);
+ String suffix = url.substring(suffixIndex);
+ String lookupPath = url.substring(this.indexLookupPath, suffixIndex);
+ lookupPath = this.resourceUrlProvider.getForLookupPath(lookupPath);
+ if (lookupPath != null) {
+ return this.prefixLookupPath + lookupPath + suffix;
+ }
+ }
+ return null;
+ }
+
private int getQueryParamsIndex(String url) {
int index = url.indexOf('?');
return (index > 0 ? index : url.length());
}
}
+
+ private static class ResourceUrlEncodingResponseWrapper extends HttpServletResponseWrapper {
+
+ private final ResourceUrlEncodingRequestWrapper request;
+
+ ResourceUrlEncodingResponseWrapper(ResourceUrlEncodingRequestWrapper request, HttpServletResponse wrapped) {
+ super(wrapped);
+ this.request = request;
+ }
+
+ @Override
+ public String encodeURL(String url) {
+ String urlPath = this.request.resolveUrlPath(url);
+ if (urlPath != null) {
+ return super.encodeURL(urlPath);
+ }
+ return super.encodeURL(url);
+ }
+ }
+
}