Skip to content

Commit 7d8279a

Browse files
committed
Merge branch '6.1.x'
2 parents d625b3d + e4e6910 commit 7d8279a

File tree

3 files changed

+35
-6
lines changed

3 files changed

+35
-6
lines changed

spring-core/src/main/java/org/springframework/core/io/UrlResource.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 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.
@@ -49,6 +49,7 @@ public class UrlResource extends AbstractFileResolvingResource {
4949

5050
private static final String AUTHORIZATION = "Authorization";
5151

52+
5253
/**
5354
* Original URI, if available; used for URI and File access.
5455
*/
@@ -310,7 +311,8 @@ public Resource createRelative(String relativePath) throws MalformedURLException
310311
/**
311312
* This delegate creates a {@code java.net.URL}, applying the given path
312313
* relative to the path of the underlying URL of this resource descriptor.
313-
* A leading slash will get dropped; a "#" symbol will get encoded.
314+
* <p>A leading slash will get dropped; a "#" symbol will get encoded.
315+
* Note that this method effectively cleans the combined path as of 6.1.
314316
* @since 5.2
315317
* @see #createRelative(String)
316318
* @see ResourceUtils#toRelativeURL(URL, String)

spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java

+11
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,17 @@ protected Resource convertClassLoaderURL(URL url) {
440440
}
441441
}
442442
else {
443+
String urlString = url.toString();
444+
String cleanedPath = StringUtils.cleanPath(urlString);
445+
if (!cleanedPath.equals(urlString)) {
446+
// Prefer cleaned URL, aligned with UrlResource#createRelative(String)
447+
try {
448+
return new UrlResource(ResourceUtils.toURI(cleanedPath));
449+
}
450+
catch (URISyntaxException | MalformedURLException ex) {
451+
// Fallback to regular URL construction below...
452+
}
453+
}
443454
return new UrlResource(url);
444455
}
445456
}

spring-core/src/main/java/org/springframework/util/ResourceUtils.java

+20-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 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,7 +34,7 @@
3434
* <p>Consider using Spring's Resource abstraction in the core package
3535
* for handling all kinds of file resources in a uniform manner.
3636
* {@link org.springframework.core.io.ResourceLoader}'s {@code getResource()}
37-
* method can resolve any location to an {@link org.springframework.core.io.Resource}
37+
* method can resolve any location to a {@link org.springframework.core.io.Resource}
3838
* object, which in turn allows one to obtain a {@code java.io.File} in the
3939
* file system through its {@code getFile()} method.
4040
*
@@ -101,6 +101,7 @@ public abstract class ResourceUtils {
101101
* @return whether the location qualifies as a URL
102102
* @see #CLASSPATH_URL_PREFIX
103103
* @see java.net.URL
104+
* @see #toURL(String)
104105
*/
105106
public static boolean isUrl(@Nullable String resourceLocation) {
106107
if (resourceLocation == null) {
@@ -126,6 +127,7 @@ public static boolean isUrl(@Nullable String resourceLocation) {
126127
* "classpath:" pseudo URL, a "file:" URL, or a plain file path
127128
* @return a corresponding URL object
128129
* @throws FileNotFoundException if the resource cannot be resolved to a URL
130+
* @see #toURL(String)
129131
*/
130132
public static URL getURL(String resourceLocation) throws FileNotFoundException {
131133
Assert.notNull(resourceLocation, "Resource location must not be null");
@@ -166,6 +168,7 @@ public static URL getURL(String resourceLocation) throws FileNotFoundException {
166168
* @return a corresponding File object
167169
* @throws FileNotFoundException if the resource cannot be resolved to
168170
* a file in the file system
171+
* @see #getFile(URL)
169172
*/
170173
public static File getFile(String resourceLocation) throws FileNotFoundException {
171174
Assert.notNull(resourceLocation, "Resource location must not be null");
@@ -197,6 +200,7 @@ public static File getFile(String resourceLocation) throws FileNotFoundException
197200
* @return a corresponding File object
198201
* @throws FileNotFoundException if the URL cannot be resolved to
199202
* a file in the file system
203+
* @see #getFile(URL, String)
200204
*/
201205
public static File getFile(URL resourceUrl) throws FileNotFoundException {
202206
return getFile(resourceUrl, "URL");
@@ -237,6 +241,7 @@ public static File getFile(URL resourceUrl, String description) throws FileNotFo
237241
* @throws FileNotFoundException if the URL cannot be resolved to
238242
* a file in the file system
239243
* @since 2.5
244+
* @see #getFile(URI, String)
240245
*/
241246
public static File getFile(URI resourceUri) throws FileNotFoundException {
242247
return getFile(resourceUri, "URI");
@@ -268,6 +273,7 @@ public static File getFile(URI resourceUri, String description) throws FileNotFo
268273
* i.e. has protocol "file", "vfsfile" or "vfs".
269274
* @param url the URL to check
270275
* @return whether the URL has been identified as a file system URL
276+
* @see #isJarURL(URL)
271277
*/
272278
public static boolean isFileURL(URL url) {
273279
String protocol = url.getProtocol();
@@ -281,6 +287,7 @@ public static boolean isFileURL(URL url) {
281287
* "vfszip", or "wsjar".
282288
* @param url the URL to check
283289
* @return whether the URL has been identified as a JAR URL
290+
* @see #isJarFileURL(URL)
284291
*/
285292
public static boolean isJarURL(URL url) {
286293
String protocol = url.getProtocol();
@@ -295,6 +302,7 @@ public static boolean isJarURL(URL url) {
295302
* @param url the URL to check
296303
* @return whether the URL has been identified as a JAR file URL
297304
* @since 4.1
305+
* @see #extractJarFileURL(URL)
298306
*/
299307
public static boolean isJarFileURL(URL url) {
300308
return (URL_PROTOCOL_FILE.equals(url.getProtocol()) &&
@@ -307,6 +315,7 @@ public static boolean isJarFileURL(URL url) {
307315
* @param jarUrl the original URL
308316
* @return the URL for the actual jar file
309317
* @throws MalformedURLException if no valid jar file URL could be extracted
318+
* @see #extractArchiveURL(URL)
310319
*/
311320
public static URL extractJarFileURL(URL jarUrl) throws MalformedURLException {
312321
String urlFile = jarUrl.getFile();
@@ -368,6 +377,7 @@ public static URL extractArchiveURL(URL jarUrl) throws MalformedURLException {
368377
* @return the URI instance
369378
* @throws URISyntaxException if the URL wasn't a valid URI
370379
* @see java.net.URL#toURI()
380+
* @see #toURI(String)
371381
*/
372382
public static URI toURI(URL url) throws URISyntaxException {
373383
return toURI(url.toString());
@@ -379,18 +389,21 @@ public static URI toURI(URL url) throws URISyntaxException {
379389
* @param location the location String to convert into a URI instance
380390
* @return the URI instance
381391
* @throws URISyntaxException if the location wasn't a valid URI
392+
* @see #toURI(URL)
382393
*/
383394
public static URI toURI(String location) throws URISyntaxException {
384395
return new URI(StringUtils.replace(location, " ", "%20"));
385396
}
386397

387398
/**
388-
* Create a URL instance for the given location String,
399+
* Create a clean URL instance for the given location String,
389400
* going through URI construction and then URL conversion.
390401
* @param location the location String to convert into a URL instance
391402
* @return the URL instance
392403
* @throws MalformedURLException if the location wasn't a valid URL
393404
* @since 6.0
405+
* @see java.net.URI#toURL()
406+
* @see #toURI(String)
394407
*/
395408
@SuppressWarnings("deprecation") // on JDK 20
396409
public static URL toURL(String location) throws MalformedURLException {
@@ -406,13 +419,15 @@ public static URL toURL(String location) throws MalformedURLException {
406419
}
407420

408421
/**
409-
* Create a URL instance for the given root URL and relative path,
422+
* Create a clean URL instance for the given root URL and relative path,
410423
* going through URI construction and then URL conversion.
411424
* @param root the root URL to start from
412425
* @param relativePath the relative path to apply
413426
* @return the relative URL instance
414427
* @throws MalformedURLException if the end result is not a valid URL
415428
* @since 6.0
429+
* @see #toURL(String)
430+
* @see StringUtils#applyRelativePath
416431
*/
417432
public static URL toRelativeURL(URL root, String relativePath) throws MalformedURLException {
418433
// # can appear in filenames, java.net.URL should not treat it as a fragment
@@ -426,6 +441,7 @@ public static URL toRelativeURL(URL root, String relativePath) throws MalformedU
426441
* given connection, preferring {@code false} but leaving the flag at
427442
* its JVM default value for jar resources (typically {@code true}).
428443
* @param con the URLConnection to set the flag on
444+
* @see URLConnection#setUseCaches
429445
*/
430446
public static void useCachesIfNecessary(URLConnection con) {
431447
if (!(con instanceof JarURLConnection)) {

0 commit comments

Comments
 (0)