diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/accept/PathExtensionContentTypeResolver.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/accept/PathExtensionContentTypeResolver.java
index 09c1465d097..a204f3312e8 100644
--- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/accept/PathExtensionContentTypeResolver.java
+++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/accept/PathExtensionContentTypeResolver.java
@@ -26,7 +26,7 @@ import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.server.NotAcceptableStatusException;
import org.springframework.web.server.ServerWebExchange;
-import org.springframework.web.util.WebUtils;
+import org.springframework.web.util.UriUtils;
/**
* A {@link RequestedContentTypeResolver} that extracts the file extension from
@@ -84,8 +84,7 @@ public class PathExtensionContentTypeResolver extends AbstractMappingContentType
@Override
protected String extractKey(ServerWebExchange exchange) {
String path = exchange.getRequest().getURI().getRawPath();
- String filename = WebUtils.extractFullFilenameFromUrlPath(path);
- String extension = StringUtils.getFilenameExtension(filename);
+ String extension = UriUtils.extractFileExtension(path);
return (StringUtils.hasText(extension)) ? extension.toLowerCase(Locale.ENGLISH) : null;
}
diff --git a/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java
index 81d3fd1e5e2..23bcc9c712d 100644
--- a/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java
+++ b/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java
@@ -31,8 +31,8 @@ import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.util.UriUtils;
import org.springframework.web.util.UrlPathHelper;
-import org.springframework.web.util.WebUtils;
/**
* A {@code ContentNegotiationStrategy} that resolves the file extension in the
@@ -114,9 +114,8 @@ public class PathExtensionContentNegotiationStrategy extends AbstractMappingCont
return null;
}
String path = this.urlPathHelper.getLookupPathForRequest(request);
- String filename = WebUtils.extractFullFilenameFromUrlPath(path);
- String extension = StringUtils.getFilenameExtension(filename);
- return (StringUtils.hasText(extension)) ? extension.toLowerCase(Locale.ENGLISH) : null;
+ String extension = UriUtils.extractFileExtension(path);
+ return (StringUtils.hasText(extension) ? extension.toLowerCase(Locale.ENGLISH) : null);
}
@Override
diff --git a/spring-web/src/main/java/org/springframework/web/util/UriUtils.java b/spring-web/src/main/java/org/springframework/web/util/UriUtils.java
index c68092971fa..6b2f3e50495 100644
--- a/spring-web/src/main/java/org/springframework/web/util/UriUtils.java
+++ b/spring-web/src/main/java/org/springframework/web/util/UriUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -34,6 +34,7 @@ import org.springframework.util.Assert;
*
*
* @author Arjen Poutsma
+ * @author Juergen Hoeller
* @since 3.0
* @see RFC 3986
*/
@@ -213,4 +214,28 @@ public abstract class UriUtils {
return (changed ? new String(bos.toByteArray(), encoding) : source);
}
+ /**
+ * Extract the file extension from the given URI path.
+ * @param path the URI path (e.g. "/products/index.html")
+ * @return the extracted file extension (e.g. "html")
+ * @since 4.3.2
+ */
+ public static String extractFileExtension(String path) {
+ int end = path.indexOf('?');
+ if (end == -1) {
+ end = path.indexOf('#');
+ if (end == -1) {
+ end = path.length();
+ }
+ }
+ int begin = path.lastIndexOf('/', end) + 1;
+ int paramIndex = path.indexOf(';', begin);
+ end = (paramIndex != -1 && paramIndex < end ? paramIndex : end);
+ int extIndex = path.lastIndexOf('.', end);
+ if (extIndex != -1 && extIndex > begin) {
+ return path.substring(extIndex + 1, end);
+ }
+ return null;
+ }
+
}
diff --git a/spring-web/src/main/java/org/springframework/web/util/WebUtils.java b/spring-web/src/main/java/org/springframework/web/util/WebUtils.java
index 65a97801b53..28b79893477 100644
--- a/spring-web/src/main/java/org/springframework/web/util/WebUtils.java
+++ b/spring-web/src/main/java/org/springframework/web/util/WebUtils.java
@@ -260,7 +260,6 @@ public abstract class WebUtils {
return realPath;
}
-
/**
* Determine the session id of the given request, if any.
* @param request current HTTP request
@@ -470,20 +469,6 @@ public abstract class WebUtils {
request.removeAttribute(ERROR_SERVLET_NAME_ATTRIBUTE);
}
- /**
- * Expose the given Map as request attributes, using the keys as attribute names
- * and the values as corresponding attribute values. Keys need to be Strings.
- * @param request current HTTP request
- * @param attributes the attributes Map
- */
- public static void exposeRequestAttributes(ServletRequest request, Map attributes) {
- Assert.notNull(request, "Request must not be null");
- Assert.notNull(attributes, "Attributes Map must not be null");
- for (Map.Entry entry : attributes.entrySet()) {
- request.setAttribute(entry.getKey(), entry.getValue());
- }
- }
-
/**
* Retrieve the first cookie with the given name. Note that multiple
* cookies can have the same name but different paths or domains.
@@ -629,69 +614,6 @@ public abstract class WebUtils {
return params;
}
- /**
- * Return the target page specified in the request.
- * @param request current servlet request
- * @param paramPrefix the parameter prefix to check for
- * (e.g. "_target" for parameters like "_target1" or "_target2")
- * @param currentPage the current page, to be returned as fallback
- * if no target page specified
- * @return the page specified in the request, or current page if not found
- */
- public static int getTargetPage(ServletRequest request, String paramPrefix, int currentPage) {
- Enumeration paramNames = request.getParameterNames();
- while (paramNames.hasMoreElements()) {
- String paramName = paramNames.nextElement();
- if (paramName.startsWith(paramPrefix)) {
- for (int i = 0; i < WebUtils.SUBMIT_IMAGE_SUFFIXES.length; i++) {
- String suffix = WebUtils.SUBMIT_IMAGE_SUFFIXES[i];
- if (paramName.endsWith(suffix)) {
- paramName = paramName.substring(0, paramName.length() - suffix.length());
- }
- }
- return Integer.parseInt(paramName.substring(paramPrefix.length()));
- }
- }
- return currentPage;
- }
-
-
- /**
- * Extract the URL filename from the given request URL path.
- * Correctly resolves nested paths such as "/products/view.html" as well.
- * @param urlPath the request URL path (e.g. "/index.html")
- * @return the extracted URI filename (e.g. "index")
- */
- public static String extractFilenameFromUrlPath(String urlPath) {
- String filename = extractFullFilenameFromUrlPath(urlPath);
- int dotIndex = filename.lastIndexOf('.');
- if (dotIndex != -1) {
- filename = filename.substring(0, dotIndex);
- }
- return filename;
- }
-
- /**
- * Extract the full URL filename (including file extension) from the given
- * request URL path. Correctly resolve nested paths such as
- * "/products/view.html" and remove any path and or query parameters.
- * @param urlPath the request URL path (e.g. "/products/index.html")
- * @return the extracted URI filename (e.g. "index.html")
- */
- public static String extractFullFilenameFromUrlPath(String urlPath) {
- int end = urlPath.indexOf('?');
- if (end == -1) {
- end = urlPath.indexOf('#');
- if (end == -1) {
- end = urlPath.length();
- }
- }
- int begin = urlPath.lastIndexOf('/', end) + 1;
- int paramIndex = urlPath.indexOf(';', begin);
- end = (paramIndex != -1 && paramIndex < end ? paramIndex : end);
- return urlPath.substring(begin, end);
- }
-
/**
* Parse the given string with matrix variables. An example string would look
* like this {@code "q1=a;q1=b;q2=a,b,c"}. The resulting map would contain
diff --git a/spring-web/src/test/java/org/springframework/web/util/UriUtilsTests.java b/spring-web/src/test/java/org/springframework/web/util/UriUtilsTests.java
index 6480c5fa2e3..2227674abc9 100644
--- a/spring-web/src/test/java/org/springframework/web/util/UriUtilsTests.java
+++ b/spring-web/src/test/java/org/springframework/web/util/UriUtilsTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2014 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -24,6 +24,7 @@ import static org.junit.Assert.*;
/**
* @author Arjen Poutsma
+ * @author Juergen Hoeller
*/
public class UriUtilsTests {
@@ -104,4 +105,22 @@ public class UriUtilsTests {
UriUtils.decode("foo%2", ENC);
}
+ @Test
+ public void extractFileExtension() {
+ assertEquals("html", UriUtils.extractFileExtension("index.html"));
+ assertEquals("html", UriUtils.extractFileExtension("/index.html"));
+ assertEquals("html", UriUtils.extractFileExtension("/products/view.html"));
+ assertEquals("html", UriUtils.extractFileExtension("/products/view.html#/a"));
+ assertEquals("html", UriUtils.extractFileExtension("/products/view.html#/path/a"));
+ assertEquals("html", UriUtils.extractFileExtension("/products/view.html#/path/a.do"));
+ assertEquals("html", UriUtils.extractFileExtension("/products/view.html?param=a"));
+ assertEquals("html", UriUtils.extractFileExtension("/products/view.html?param=/path/a"));
+ assertEquals("html", UriUtils.extractFileExtension("/products/view.html?param=/path/a.do"));
+ assertEquals("html", UriUtils.extractFileExtension("/products/view.html?param=/path/a#/path/a"));
+ assertEquals("html", UriUtils.extractFileExtension("/products/view.html?param=/path/a.do#/path/a.do"));
+ assertEquals("html", UriUtils.extractFileExtension("/products;q=11/view.html?param=/path/a.do"));
+ assertEquals("html", UriUtils.extractFileExtension("/products;q=11/view.html;r=22?param=/path/a.do"));
+ assertEquals("html", UriUtils.extractFileExtension("/products;q=11/view.html;r=22;s=33?param=/path/a.do"));
+ }
+
}
diff --git a/spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java b/spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java
index be7a5b55348..201c7cda4f7 100644
--- a/spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java
+++ b/spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java
@@ -55,34 +55,6 @@ public class WebUtilsTests {
assertEquals("myValue4", WebUtils.findParameterValue(params, "myKey4"));
}
- @Test
- public void extractFilenameFromUrlPath() {
- assertEquals("index", WebUtils.extractFilenameFromUrlPath("index.html"));
- assertEquals("index", WebUtils.extractFilenameFromUrlPath("/index.html"));
- assertEquals("view", WebUtils.extractFilenameFromUrlPath("/products/view.html"));
- assertEquals("view", WebUtils.extractFilenameFromUrlPath("/products/view.html?param=a"));
- assertEquals("view", WebUtils.extractFilenameFromUrlPath("/products/view.html?param=/path/a"));
- assertEquals("view", WebUtils.extractFilenameFromUrlPath("/products/view.html?param=/path/a.do"));
- }
-
- @Test
- public void extractFullFilenameFromUrlPath() {
- assertEquals("index.html", WebUtils.extractFullFilenameFromUrlPath("index.html"));
- assertEquals("index.html", WebUtils.extractFullFilenameFromUrlPath("/index.html"));
- assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html"));
- assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html#/a"));
- assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html#/path/a"));
- assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html#/path/a.do"));
- assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html?param=a"));
- assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html?param=/path/a"));
- assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html?param=/path/a.do"));
- assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html?param=/path/a#/path/a"));
- assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html?param=/path/a.do#/path/a.do"));
- assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products;q=11/view.html?param=/path/a.do"));
- assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products;q=11/view.html;r=22?param=/path/a.do"));
- assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products;q=11/view.html;r=22;s=33?param=/path/a.do"));
- }
-
@Test
public void parseMatrixVariablesString() {
MultiValueMap variables;
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java
index 852f5cd2dc7..367aed85033 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java
@@ -28,8 +28,8 @@ import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
+import org.springframework.web.util.UriUtils;
import org.springframework.web.util.UrlPathHelper;
-import org.springframework.web.util.WebUtils;
/**
* A UriComponentsBuilder that extracts information from the HttpServletRequest.
@@ -44,7 +44,6 @@ public class ServletUriComponentsBuilder extends UriComponentsBuilder {
/**
* Default constructor. Protected to prevent direct instantiation.
- *
* @see #fromContextPath(HttpServletRequest)
* @see #fromServletMapping(HttpServletRequest)
* @see #fromRequest(HttpServletRequest)
@@ -219,8 +218,7 @@ public class ServletUriComponentsBuilder extends UriComponentsBuilder {
public String removePathExtension() {
String extension = null;
if (this.originalPath != null) {
- String filename = WebUtils.extractFullFilenameFromUrlPath(this.originalPath);
- extension = StringUtils.getFilenameExtension(filename);
+ extension = UriUtils.extractFileExtension(this.originalPath);
if (!StringUtils.isEmpty(extension)) {
int end = this.originalPath.length() - (extension.length() + 1);
replacePath(this.originalPath.substring(0, end));