Browse Source

Preserve URLStreamHandler in toRelativeURL and convertClassLoaderURL

Closes gh-33561
See gh-33199
pull/33720/head
Juergen Hoeller 1 year ago
parent
commit
daa109e2ec
  1. 11
      spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java
  2. 8
      spring-core/src/main/java/org/springframework/util/ResourceUtils.java
  3. 7
      spring-core/src/test/java/org/springframework/core/io/ResourceTests.java

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

@ -412,6 +412,7 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
* @see #doFindAllClassPathResources * @see #doFindAllClassPathResources
* @see #doFindPathMatchingFileResources * @see #doFindPathMatchingFileResources
*/ */
@SuppressWarnings("deprecation") // on JDK 20 (deprecated URL constructor)
protected Resource convertClassLoaderURL(URL url) { protected Resource convertClassLoaderURL(URL url) {
if (ResourceUtils.URL_PROTOCOL_FILE.equals(url.getProtocol())) { if (ResourceUtils.URL_PROTOCOL_FILE.equals(url.getProtocol())) {
try { try {
@ -429,14 +430,10 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
if (!cleanedPath.equals(urlString)) { if (!cleanedPath.equals(urlString)) {
// Prefer cleaned URL, aligned with UrlResource#createRelative(String) // Prefer cleaned URL, aligned with UrlResource#createRelative(String)
try { try {
// Cannot test for URLStreamHandler directly: URL equality for same String // Retain original URL instance, potentially including custom URLStreamHandler.
// in order to find out whether original URL uses default URLStreamHandler. return new UrlResource(new URL(url, cleanedPath));
if (ResourceUtils.toURL(urlString).equals(url)) {
// Plain URL with default URLStreamHandler -> replace with cleaned path.
return new UrlResource(ResourceUtils.toURI(cleanedPath));
}
} }
catch (URISyntaxException | MalformedURLException ex) { catch (MalformedURLException ex) {
// Fallback to regular URL construction below... // Fallback to regular URL construction below...
} }
} }

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

@ -405,14 +405,14 @@ public abstract class ResourceUtils {
* @see java.net.URI#toURL() * @see java.net.URI#toURL()
* @see #toURI(String) * @see #toURI(String)
*/ */
@SuppressWarnings("deprecation") // on JDK 20 @SuppressWarnings("deprecation") // on JDK 20 (deprecated URL constructor)
public static URL toURL(String location) throws MalformedURLException { public static URL toURL(String location) throws MalformedURLException {
try { try {
// Prefer URI construction with toURL conversion (as of 6.1) // Prefer URI construction with toURL conversion (as of 6.1)
return toURI(StringUtils.cleanPath(location)).toURL(); return toURI(StringUtils.cleanPath(location)).toURL();
} }
catch (URISyntaxException | IllegalArgumentException ex) { 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. // e.g. for decoded location Strings with percent characters.
return new URL(location); return new URL(location);
} }
@ -429,11 +429,13 @@ public abstract class ResourceUtils {
* @see #toURL(String) * @see #toURL(String)
* @see StringUtils#applyRelativePath * @see StringUtils#applyRelativePath
*/ */
@SuppressWarnings("deprecation") // on JDK 20 (deprecated URL constructor)
public static URL toRelativeURL(URL root, String relativePath) throws MalformedURLException { public static URL toRelativeURL(URL root, String relativePath) throws MalformedURLException {
// # can appear in filenames, java.net.URL should not treat it as a fragment // # can appear in filenames, java.net.URL should not treat it as a fragment
relativePath = StringUtils.replace(relativePath, "#", "%23"); 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)));
} }
/** /**

7
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")); 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 @Test
void missingRemoteResourceDoesNotExist() throws Exception { void missingRemoteResourceDoesNotExist() throws Exception {
String baseUrl = startServer(); String baseUrl = startServer();

Loading…
Cancel
Save