Skip to content

Commit b583aa1

Browse files
committed
Avoid dependency on WebUtils for extracting file extension
Issue: SPR-14479 (cherry picked from commit adc595b)
1 parent e0d81b9 commit b583aa1

File tree

5 files changed

+66
-15
lines changed

5 files changed

+66
-15
lines changed

spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
import org.springframework.util.StringUtils;
3636
import org.springframework.web.HttpMediaTypeNotAcceptableException;
3737
import org.springframework.web.context.request.NativeWebRequest;
38+
import org.springframework.web.util.UriUtils;
3839
import org.springframework.web.util.UrlPathHelper;
39-
import org.springframework.web.util.WebUtils;
4040

4141
/**
4242
* A {@code ContentNegotiationStrategy} that resolves the file extension in the
@@ -118,17 +118,16 @@ protected String getMediaTypeKey(NativeWebRequest webRequest) {
118118
return null;
119119
}
120120
String path = this.urlPathHelper.getLookupPathForRequest(request);
121-
String filename = WebUtils.extractFullFilenameFromUrlPath(path);
122-
String extension = StringUtils.getFilenameExtension(filename);
123-
return (StringUtils.hasText(extension)) ? extension.toLowerCase(Locale.ENGLISH) : null;
121+
String extension = UriUtils.extractFileExtension(path);
122+
return (StringUtils.hasText(extension) ? extension.toLowerCase(Locale.ENGLISH) : null);
124123
}
125124

126125
@Override
127126
protected MediaType handleNoMatch(NativeWebRequest webRequest, String extension)
128127
throws HttpMediaTypeNotAcceptableException {
129128

130129
if (this.useJaf && JAF_PRESENT) {
131-
MediaType mediaType = JafMediaTypeFactory.getMediaType("file." + extension);
130+
MediaType mediaType = ActivationMediaTypeFactory.getMediaType("file." + extension);
132131
if (mediaType != null && !MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) {
133132
return mediaType;
134133
}
@@ -157,7 +156,7 @@ public MediaType getMediaTypeForResource(Resource resource) {
157156
mediaType = lookupMediaType(extension);
158157
}
159158
if (mediaType == null && JAF_PRESENT) {
160-
mediaType = JafMediaTypeFactory.getMediaType(filename);
159+
mediaType = ActivationMediaTypeFactory.getMediaType(filename);
161160
}
162161
if (MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) {
163162
mediaType = null;
@@ -169,7 +168,7 @@ public MediaType getMediaTypeForResource(Resource resource) {
169168
/**
170169
* Inner class to avoid hard-coded dependency on JAF.
171170
*/
172-
private static class JafMediaTypeFactory {
171+
private static class ActivationMediaTypeFactory {
173172

174173
private static final FileTypeMap fileTypeMap;
175174

spring-web/src/main/java/org/springframework/web/util/UriUtils.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@
3434
* </ul>
3535
*
3636
* @author Arjen Poutsma
37+
* @author Juergen Hoeller
3738
* @since 3.0
3839
* @see <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>
3940
*/
@@ -213,4 +214,28 @@ public static String decode(String source, String encoding) throws UnsupportedEn
213214
return (changed ? new String(bos.toByteArray(), encoding) : source);
214215
}
215216

217+
/**
218+
* Extract the file extension from the given URI path.
219+
* @param path the URI path (e.g. "/products/index.html")
220+
* @return the extracted file extension (e.g. "html")
221+
* @since 4.3.2
222+
*/
223+
public static String extractFileExtension(String path) {
224+
int end = path.indexOf('?');
225+
if (end == -1) {
226+
end = path.indexOf('#');
227+
if (end == -1) {
228+
end = path.length();
229+
}
230+
}
231+
int begin = path.lastIndexOf('/', end) + 1;
232+
int paramIndex = path.indexOf(';', begin);
233+
end = (paramIndex != -1 && paramIndex < end ? paramIndex : end);
234+
int extIndex = path.lastIndexOf('.', end);
235+
if (extIndex != -1 && extIndex > begin) {
236+
return path.substring(extIndex + 1, end);
237+
}
238+
return null;
239+
}
240+
216241
}

spring-web/src/main/java/org/springframework/web/util/WebUtils.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -278,7 +278,6 @@ public static String getRealPath(ServletContext servletContext, String path) thr
278278
return realPath;
279279
}
280280

281-
282281
/**
283282
* Determine the session id of the given request, if any.
284283
* @param request current HTTP request
@@ -353,7 +352,9 @@ public static void setSessionAttribute(HttpServletRequest request, String name,
353352
* @param clazz the class to instantiate for a new attribute
354353
* @return the value of the session attribute, newly created if not found
355354
* @throws IllegalArgumentException if the session attribute could not be instantiated
355+
* @deprecated as of Spring 4.3.2, in favor of custom code for such purposes
356356
*/
357+
@Deprecated
357358
public static Object getOrCreateSessionAttribute(HttpSession session, String name, Class<?> clazz)
358359
throws IllegalArgumentException {
359360

@@ -527,7 +528,9 @@ public static void clearErrorRequestAttributes(HttpServletRequest request) {
527528
* and the values as corresponding attribute values. Keys need to be Strings.
528529
* @param request current HTTP request
529530
* @param attributes the attributes Map
531+
* @deprecated as of Spring 4.3.2, in favor of custom code for such purposes
530532
*/
533+
@Deprecated
531534
public static void exposeRequestAttributes(ServletRequest request, Map<String, ?> attributes) {
532535
Assert.notNull(request, "Request must not be null");
533536
Assert.notNull(attributes, "Attributes Map must not be null");
@@ -689,7 +692,9 @@ else if (values.length > 1) {
689692
* @param currentPage the current page, to be returned as fallback
690693
* if no target page specified
691694
* @return the page specified in the request, or current page if not found
695+
* @deprecated as of Spring 4.3.2, in favor of custom code for such purposes
692696
*/
697+
@Deprecated
693698
public static int getTargetPage(ServletRequest request, String paramPrefix, int currentPage) {
694699
Enumeration<String> paramNames = request.getParameterNames();
695700
while (paramNames.hasMoreElements()) {
@@ -713,7 +718,9 @@ public static int getTargetPage(ServletRequest request, String paramPrefix, int
713718
* Correctly resolves nested paths such as "/products/view.html" as well.
714719
* @param urlPath the request URL path (e.g. "/index.html")
715720
* @return the extracted URI filename (e.g. "index")
721+
* @deprecated as of Spring 4.3.2, in favor of custom code for such purposes
716722
*/
723+
@Deprecated
717724
public static String extractFilenameFromUrlPath(String urlPath) {
718725
String filename = extractFullFilenameFromUrlPath(urlPath);
719726
int dotIndex = filename.lastIndexOf('.');
@@ -729,7 +736,10 @@ public static String extractFilenameFromUrlPath(String urlPath) {
729736
* "/products/view.html" and remove any path and or query parameters.
730737
* @param urlPath the request URL path (e.g. "/products/index.html")
731738
* @return the extracted URI filename (e.g. "index.html")
739+
* @deprecated as of Spring 4.3.2, in favor of custom code for such purposes
740+
* (or {@link UriUtils#extractFileExtension} for the file extension use case)
732741
*/
742+
@Deprecated
733743
public static String extractFullFilenameFromUrlPath(String urlPath) {
734744
int end = urlPath.indexOf('?');
735745
if (end == -1) {

spring-web/src/test/java/org/springframework/web/util/UriUtilsTests.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
2424

2525
/**
2626
* @author Arjen Poutsma
27+
* @author Juergen Hoeller
2728
*/
2829
public class UriUtilsTests {
2930

@@ -104,4 +105,22 @@ public void decodeInvalidSequence() throws UnsupportedEncodingException {
104105
UriUtils.decode("foo%2", ENC);
105106
}
106107

108+
@Test
109+
public void extractFileExtension() {
110+
assertEquals("html", UriUtils.extractFileExtension("index.html"));
111+
assertEquals("html", UriUtils.extractFileExtension("/index.html"));
112+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html"));
113+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html#/a"));
114+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html#/path/a"));
115+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html#/path/a.do"));
116+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html?param=a"));
117+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html?param=/path/a"));
118+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html?param=/path/a.do"));
119+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html?param=/path/a#/path/a"));
120+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html?param=/path/a.do#/path/a.do"));
121+
assertEquals("html", UriUtils.extractFileExtension("/products;q=11/view.html?param=/path/a.do"));
122+
assertEquals("html", UriUtils.extractFileExtension("/products;q=11/view.html;r=22?param=/path/a.do"));
123+
assertEquals("html", UriUtils.extractFileExtension("/products;q=11/view.html;r=22;s=33?param=/path/a.do"));
124+
}
125+
107126
}

spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
import org.springframework.web.context.request.ServletRequestAttributes;
2929
import org.springframework.web.util.UriComponents;
3030
import org.springframework.web.util.UriComponentsBuilder;
31+
import org.springframework.web.util.UriUtils;
3132
import org.springframework.web.util.UrlPathHelper;
32-
import org.springframework.web.util.WebUtils;
3333

3434
/**
3535
* A UriComponentsBuilder that extracts information from the HttpServletRequest.
@@ -44,7 +44,6 @@ public class ServletUriComponentsBuilder extends UriComponentsBuilder {
4444

4545
/**
4646
* Default constructor. Protected to prevent direct instantiation.
47-
*
4847
* @see #fromContextPath(HttpServletRequest)
4948
* @see #fromServletMapping(HttpServletRequest)
5049
* @see #fromRequest(HttpServletRequest)
@@ -219,8 +218,7 @@ private void initPath(String path) {
219218
public String removePathExtension() {
220219
String extension = null;
221220
if (this.originalPath != null) {
222-
String filename = WebUtils.extractFullFilenameFromUrlPath(this.originalPath);
223-
extension = StringUtils.getFilenameExtension(filename);
221+
extension = UriUtils.extractFileExtension(this.originalPath);
224222
if (!StringUtils.isEmpty(extension)) {
225223
int end = this.originalPath.length() - (extension.length() + 1);
226224
replacePath(this.originalPath.substring(0, end));

0 commit comments

Comments
 (0)