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 0a042f4384..000b637964 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
@@ -35,8 +35,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
@@ -118,9 +118,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
@@ -128,7 +127,7 @@ public class PathExtensionContentNegotiationStrategy extends AbstractMappingCont
throws HttpMediaTypeNotAcceptableException {
if (this.useJaf && JAF_PRESENT) {
- MediaType mediaType = JafMediaTypeFactory.getMediaType("file." + extension);
+ MediaType mediaType = ActivationMediaTypeFactory.getMediaType("file." + extension);
if (mediaType != null && !MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) {
return mediaType;
}
@@ -157,7 +156,7 @@ public class PathExtensionContentNegotiationStrategy extends AbstractMappingCont
mediaType = lookupMediaType(extension);
}
if (mediaType == null && JAF_PRESENT) {
- mediaType = JafMediaTypeFactory.getMediaType(filename);
+ mediaType = ActivationMediaTypeFactory.getMediaType(filename);
}
if (MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) {
mediaType = null;
@@ -169,7 +168,7 @@ public class PathExtensionContentNegotiationStrategy extends AbstractMappingCont
/**
* Inner class to avoid hard-coded dependency on JAF.
*/
- private static class JafMediaTypeFactory {
+ private static class ActivationMediaTypeFactory {
private static final FileTypeMap fileTypeMap;
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 c68092971f..6b2f3e5049 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 6d8062fbdc..13195a76a7 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
@@ -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.
@@ -278,7 +278,6 @@ public abstract class WebUtils {
return realPath;
}
-
/**
* Determine the session id of the given request, if any.
* @param request current HTTP request
@@ -353,7 +352,9 @@ public abstract class WebUtils {
* @param clazz the class to instantiate for a new attribute
* @return the value of the session attribute, newly created if not found
* @throws IllegalArgumentException if the session attribute could not be instantiated
+ * @deprecated as of Spring 4.3.2, in favor of custom code for such purposes
*/
+ @Deprecated
public static Object getOrCreateSessionAttribute(HttpSession session, String name, Class> clazz)
throws IllegalArgumentException {
@@ -527,7 +528,9 @@ public abstract class WebUtils {
* and the values as corresponding attribute values. Keys need to be Strings.
* @param request current HTTP request
* @param attributes the attributes Map
+ * @deprecated as of Spring 4.3.2, in favor of custom code for such purposes
*/
+ @Deprecated
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");
@@ -689,7 +692,9 @@ public abstract class WebUtils {
* @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
+ * @deprecated as of Spring 4.3.2, in favor of custom code for such purposes
*/
+ @Deprecated
public static int getTargetPage(ServletRequest request, String paramPrefix, int currentPage) {
Enumeration paramNames = request.getParameterNames();
while (paramNames.hasMoreElements()) {
@@ -713,7 +718,9 @@ public abstract class WebUtils {
* 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")
+ * @deprecated as of Spring 4.3.2, in favor of custom code for such purposes
*/
+ @Deprecated
public static String extractFilenameFromUrlPath(String urlPath) {
String filename = extractFullFilenameFromUrlPath(urlPath);
int dotIndex = filename.lastIndexOf('.');
@@ -729,7 +736,10 @@ public abstract class WebUtils {
* "/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")
+ * @deprecated as of Spring 4.3.2, in favor of custom code for such purposes
+ * (or {@link UriUtils#extractFileExtension} for the file extension use case)
*/
+ @Deprecated
public static String extractFullFilenameFromUrlPath(String urlPath) {
int end = urlPath.indexOf('?');
if (end == -1) {
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 6480c5fa2e..2227674abc 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-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 852f5cd2dc..367aed8503 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));