diff --git a/spring-core/src/main/java/org/springframework/core/io/UrlResource.java b/spring-core/src/main/java/org/springframework/core/io/UrlResource.java index ef426dc681..bfa0f09d32 100644 --- a/spring-core/src/main/java/org/springframework/core/io/UrlResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/UrlResource.java @@ -332,13 +332,15 @@ public class UrlResource extends AbstractFileResolvingResource { @Nullable public String getFilename() { if (this.uri != null) { - // URI path is decoded and has standard separators - return StringUtils.getFilename(this.uri.getPath()); - } - else { - String filename = StringUtils.getFilename(StringUtils.cleanPath(this.url.getPath())); - return (filename != null ? URLDecoder.decode(filename, StandardCharsets.UTF_8) : null); + String path = this.uri.getPath(); + if (path != null) { + // Prefer URI path: decoded and has standard separators + return StringUtils.getFilename(this.uri.getPath()); + } } + // Otherwise, process URL path + String filename = StringUtils.getFilename(StringUtils.cleanPath(this.url.getPath())); + return (filename != null ? URLDecoder.decode(filename, StandardCharsets.UTF_8) : null); } /** 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 b5a68d27ed..742fa2c925 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 @@ -302,11 +302,28 @@ class ResourceTests { @Test void filenameIsExtractedFromFilePath() throws Exception { + assertThat(new UrlResource("file:test?argh").getFilename()).isEqualTo("test"); + assertThat(new UrlResource("file:/test?argh").getFilename()).isEqualTo("test"); + assertThat(new UrlResource("file:test.txt?argh").getFilename()).isEqualTo("test.txt"); + assertThat(new UrlResource("file:/test.txt?argh").getFilename()).isEqualTo("test.txt"); + assertThat(new UrlResource("file:/dir/test?argh").getFilename()).isEqualTo("test"); assertThat(new UrlResource("file:/dir/test.txt?argh").getFilename()).isEqualTo("test.txt"); assertThat(new UrlResource("file:\\dir\\test.txt?argh").getFilename()).isEqualTo("test.txt"); assertThat(new UrlResource("file:\\dir/test.txt?argh").getFilename()).isEqualTo("test.txt"); } + @Test + void filenameIsExtractedFromURL() throws Exception { + assertThat(new UrlResource(new URL("file:test?argh")).getFilename()).isEqualTo("test"); + assertThat(new UrlResource(new URL("file:/test?argh")).getFilename()).isEqualTo("test"); + assertThat(new UrlResource(new URL("file:test.txt?argh")).getFilename()).isEqualTo("test.txt"); + assertThat(new UrlResource(new URL("file:/test.txt?argh")).getFilename()).isEqualTo("test.txt"); + assertThat(new UrlResource(new URL("file:/dir/test?argh")).getFilename()).isEqualTo("test"); + assertThat(new UrlResource(new URL("file:/dir/test.txt?argh")).getFilename()).isEqualTo("test.txt"); + assertThat(new UrlResource(new URL("file:\\dir\\test.txt?argh")).getFilename()).isEqualTo("test.txt"); + assertThat(new UrlResource(new URL("file:\\dir/test.txt?argh")).getFilename()).isEqualTo("test.txt"); + } + @Test void filenameContainingHashTagIsExtractedFromFilePathUnencoded() throws Exception { String unencodedPath = "/dir/test#1.txt";