Skip to content

Commit f07e7ab

Browse files
committed
Create UrlResource factory methods that throw unchecked exceptions
UrlResource constructors throw checked exceptions which makes it difficult to use them in java.util.Stream and java.util.Optional APIs or other scenarios when a checked IOException is undesirable. To support such use cases, this commit introduces `from(URI)` and `from(String)` factory methods in UrlResource that throw UncheckedIOExceptions. Closes gh-28501
1 parent 4515180 commit f07e7ab

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

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

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -19,6 +19,7 @@
1919
import java.io.File;
2020
import java.io.IOException;
2121
import java.io.InputStream;
22+
import java.io.UncheckedIOException;
2223
import java.net.HttpURLConnection;
2324
import java.net.MalformedURLException;
2425
import java.net.URI;
@@ -37,6 +38,7 @@
3738
* case of the {@code "file:"} protocol.
3839
*
3940
* @author Juergen Hoeller
41+
* @author Sam Brannen
4042
* @since 28.12.2003
4143
* @see java.net.URL
4244
*/
@@ -135,6 +137,49 @@ public UrlResource(String protocol, String location, @Nullable String fragment)
135137
}
136138

137139

140+
/**
141+
* Create a new {@code UrlResource} from the given {@link URI}.
142+
* <p>This factory method is a convenience for {@link #UrlResource(URI)} that
143+
* catches any {@link MalformedURLException} and rethrows it wrapped in an
144+
* {@link UncheckedIOException}; suitable for use in {@link java.util.Stream}
145+
* and {@link java.util.Optional} APIs or other scenarios when a checked
146+
* {@link IOException} is undesirable.
147+
* @param uri a URI
148+
* @throws UncheckedIOException if the given URL path is not valid
149+
* @since 6.0
150+
* @see #UrlResource(URI)
151+
*/
152+
public static UrlResource from(URI uri) throws UncheckedIOException {
153+
try {
154+
return new UrlResource(uri);
155+
}
156+
catch (MalformedURLException ex) {
157+
throw new UncheckedIOException(ex);
158+
}
159+
}
160+
161+
/**
162+
* Create a new {@code UrlResource} from the given URL path.
163+
* <p>This factory method is a convenience for {@link #UrlResource(String)}
164+
* that catches any {@link MalformedURLException} and rethrows it wrapped in an
165+
* {@link UncheckedIOException}; suitable for use in {@link java.util.Stream}
166+
* and {@link java.util.Optional} APIs or other scenarios when a checked
167+
* {@link IOException} is undesirable.
168+
* @param path a URL path
169+
* @throws UncheckedIOException if the given URL path is not valid
170+
* @since 6.0
171+
* @see #UrlResource(String)
172+
*/
173+
public static UrlResource from(String path) throws UncheckedIOException {
174+
try {
175+
return new UrlResource(path);
176+
}
177+
catch (MalformedURLException ex) {
178+
throw new UncheckedIOException(ex);
179+
}
180+
}
181+
182+
138183
/**
139184
* Determine a cleaned URL for the given original URL.
140185
* @param originalUrl the original URL

spring-core/src/test/java/org/springframework/core/io/ResourceTests.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -208,6 +208,21 @@ private void doTestResource(Resource resource) throws IOException {
208208
relative4::lastModified);
209209
}
210210

211+
@Test
212+
void urlResourceFactoryMethods() throws IOException {
213+
Resource resource1 = new UrlResource("file:core/io/Resource.class");
214+
Resource resource2 = UrlResource.from("file:core/io/Resource.class");
215+
Resource resource3 = UrlResource.from(resource1.getURI());
216+
217+
assertThat(resource2.getURL()).isEqualTo(resource1.getURL());
218+
assertThat(resource3.getURL()).isEqualTo(resource1.getURL());
219+
220+
assertThat(UrlResource.from("file:core/../core/io/./Resource.class")).isEqualTo(resource1);
221+
assertThat(UrlResource.from("file:/dir/test.txt?argh").getFilename()).isEqualTo("test.txt");
222+
assertThat(UrlResource.from("file:\\dir\\test.txt?argh").getFilename()).isEqualTo("test.txt");
223+
assertThat(UrlResource.from("file:\\dir/test.txt?argh").getFilename()).isEqualTo("test.txt");
224+
}
225+
211226
@Test
212227
void classPathResourceWithRelativePath() throws IOException {
213228
Resource resource = new ClassPathResource("dir/");

0 commit comments

Comments
 (0)