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
This commit is contained in:
Sam Brannen 2022-05-23 14:22:35 +02:00
parent 4515180195
commit f07e7ab39d
2 changed files with 62 additions and 2 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,6 +19,7 @@ package org.springframework.core.io;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
@ -37,6 +38,7 @@ import org.springframework.util.StringUtils;
* case of the {@code "file:"} protocol.
*
* @author Juergen Hoeller
* @author Sam Brannen
* @since 28.12.2003
* @see java.net.URL
*/
@ -135,6 +137,49 @@ public class UrlResource extends AbstractFileResolvingResource {
}
/**
* Create a new {@code UrlResource} from the given {@link URI}.
* <p>This factory method is a convenience for {@link #UrlResource(URI)} that
* catches any {@link MalformedURLException} and rethrows it wrapped in an
* {@link UncheckedIOException}; suitable for use in {@link java.util.Stream}
* and {@link java.util.Optional} APIs or other scenarios when a checked
* {@link IOException} is undesirable.
* @param uri a URI
* @throws UncheckedIOException if the given URL path is not valid
* @since 6.0
* @see #UrlResource(URI)
*/
public static UrlResource from(URI uri) throws UncheckedIOException {
try {
return new UrlResource(uri);
}
catch (MalformedURLException ex) {
throw new UncheckedIOException(ex);
}
}
/**
* Create a new {@code UrlResource} from the given URL path.
* <p>This factory method is a convenience for {@link #UrlResource(String)}
* that catches any {@link MalformedURLException} and rethrows it wrapped in an
* {@link UncheckedIOException}; suitable for use in {@link java.util.Stream}
* and {@link java.util.Optional} APIs or other scenarios when a checked
* {@link IOException} is undesirable.
* @param path a URL path
* @throws UncheckedIOException if the given URL path is not valid
* @since 6.0
* @see #UrlResource(String)
*/
public static UrlResource from(String path) throws UncheckedIOException {
try {
return new UrlResource(path);
}
catch (MalformedURLException ex) {
throw new UncheckedIOException(ex);
}
}
/**
* Determine a cleaned URL for the given original URL.
* @param originalUrl the original URL

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -208,6 +208,21 @@ class ResourceTests {
relative4::lastModified);
}
@Test
void urlResourceFactoryMethods() throws IOException {
Resource resource1 = new UrlResource("file:core/io/Resource.class");
Resource resource2 = UrlResource.from("file:core/io/Resource.class");
Resource resource3 = UrlResource.from(resource1.getURI());
assertThat(resource2.getURL()).isEqualTo(resource1.getURL());
assertThat(resource3.getURL()).isEqualTo(resource1.getURL());
assertThat(UrlResource.from("file:core/../core/io/./Resource.class")).isEqualTo(resource1);
assertThat(UrlResource.from("file:/dir/test.txt?argh").getFilename()).isEqualTo("test.txt");
assertThat(UrlResource.from("file:\\dir\\test.txt?argh").getFilename()).isEqualTo("test.txt");
assertThat(UrlResource.from("file:\\dir/test.txt?argh").getFilename()).isEqualTo("test.txt");
}
@Test
void classPathResourceWithRelativePath() throws IOException {
Resource resource = new ClassPathResource("dir/");