From daa109e2ecef0ee42499c5b9317be110ed5f48a7 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 25 Sep 2024 12:45:34 +0200 Subject: [PATCH] Preserve URLStreamHandler in toRelativeURL and convertClassLoaderURL Closes gh-33561 See gh-33199 --- .../support/PathMatchingResourcePatternResolver.java | 11 ++++------- .../java/org/springframework/util/ResourceUtils.java | 8 +++++--- .../org/springframework/core/io/ResourceTests.java | 7 +++++++ 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java b/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java index 2f68ab34297..1529dcd97df 100644 --- a/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java +++ b/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java @@ -412,6 +412,7 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol * @see #doFindAllClassPathResources * @see #doFindPathMatchingFileResources */ + @SuppressWarnings("deprecation") // on JDK 20 (deprecated URL constructor) protected Resource convertClassLoaderURL(URL url) { if (ResourceUtils.URL_PROTOCOL_FILE.equals(url.getProtocol())) { try { @@ -429,14 +430,10 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol if (!cleanedPath.equals(urlString)) { // Prefer cleaned URL, aligned with UrlResource#createRelative(String) try { - // Cannot test for URLStreamHandler directly: URL equality for same String - // in order to find out whether original URL uses default URLStreamHandler. - if (ResourceUtils.toURL(urlString).equals(url)) { - // Plain URL with default URLStreamHandler -> replace with cleaned path. - return new UrlResource(ResourceUtils.toURI(cleanedPath)); - } + // Retain original URL instance, potentially including custom URLStreamHandler. + return new UrlResource(new URL(url, cleanedPath)); } - catch (URISyntaxException | MalformedURLException ex) { + catch (MalformedURLException ex) { // Fallback to regular URL construction below... } } diff --git a/spring-core/src/main/java/org/springframework/util/ResourceUtils.java b/spring-core/src/main/java/org/springframework/util/ResourceUtils.java index ec75c898f9b..02c302752c8 100644 --- a/spring-core/src/main/java/org/springframework/util/ResourceUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ResourceUtils.java @@ -405,14 +405,14 @@ public abstract class ResourceUtils { * @see java.net.URI#toURL() * @see #toURI(String) */ - @SuppressWarnings("deprecation") // on JDK 20 + @SuppressWarnings("deprecation") // on JDK 20 (deprecated URL constructor) public static URL toURL(String location) throws MalformedURLException { try { // Prefer URI construction with toURL conversion (as of 6.1) return toURI(StringUtils.cleanPath(location)).toURL(); } catch (URISyntaxException | IllegalArgumentException ex) { - // Lenient fallback to deprecated (on JDK 20) URL constructor, + // Lenient fallback to deprecated URL constructor, // e.g. for decoded location Strings with percent characters. return new URL(location); } @@ -429,11 +429,13 @@ public abstract class ResourceUtils { * @see #toURL(String) * @see StringUtils#applyRelativePath */ + @SuppressWarnings("deprecation") // on JDK 20 (deprecated URL constructor) public static URL toRelativeURL(URL root, String relativePath) throws MalformedURLException { // # can appear in filenames, java.net.URL should not treat it as a fragment relativePath = StringUtils.replace(relativePath, "#", "%23"); - return toURL(StringUtils.applyRelativePath(root.toString(), relativePath)); + // Retain original URL instance, potentially including custom URLStreamHandler. + return new URL(root, StringUtils.cleanPath(StringUtils.applyRelativePath(root.toString(), relativePath))); } /** diff --git a/spring-core/src/test/java/org/springframework/core/io/ResourceTests.java b/spring-core/src/test/java/org/springframework/core/io/ResourceTests.java index 591254e678f..4360faa5381 100644 --- a/spring-core/src/test/java/org/springframework/core/io/ResourceTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/ResourceTests.java @@ -377,6 +377,13 @@ class ResourceTests { assertThat(relative).isEqualTo(new UrlResource("file:dir/subdir")); } + @Test + void unusualRelativeResourcesAreEqual() throws Exception { + Resource resource = new UrlResource("file:dir/"); + Resource relative = resource.createRelative("http://spring.io"); + assertThat(relative).isEqualTo(new UrlResource("file:dir/http://spring.io")); + } + @Test void missingRemoteResourceDoesNotExist() throws Exception { String baseUrl = startServer();