Skip to content

Commit ce0832a

Browse files
committed
Avoid unnecessary computation of cleaned URL
Closes gh-25531 (cherry picked from commit 96a4e11)
1 parent 286be6d commit ce0832a

File tree

1 file changed

+31
-16
lines changed

1 file changed

+31
-16
lines changed

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

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2020 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.
@@ -56,7 +56,8 @@ public class UrlResource extends AbstractFileResolvingResource {
5656
/**
5757
* Cleaned URL (with normalized path), used for comparisons.
5858
*/
59-
private final URL cleanedUrl;
59+
@Nullable
60+
private volatile URL cleanedUrl;
6061

6162

6263
/**
@@ -69,7 +70,6 @@ public UrlResource(URI uri) throws MalformedURLException {
6970
Assert.notNull(uri, "URI must not be null");
7071
this.uri = uri;
7172
this.url = uri.toURL();
72-
this.cleanedUrl = getCleanedUrl(this.url, uri.toString());
7373
}
7474

7575
/**
@@ -78,9 +78,8 @@ public UrlResource(URI uri) throws MalformedURLException {
7878
*/
7979
public UrlResource(URL url) {
8080
Assert.notNull(url, "URL must not be null");
81-
this.url = url;
82-
this.cleanedUrl = getCleanedUrl(this.url, url.toString());
8381
this.uri = null;
82+
this.url = url;
8483
}
8584

8685
/**
@@ -127,7 +126,6 @@ public UrlResource(String protocol, String location, @Nullable String fragment)
127126
try {
128127
this.uri = new URI(protocol, location, fragment);
129128
this.url = this.uri.toURL();
130-
this.cleanedUrl = getCleanedUrl(this.url, this.uri.toString());
131129
}
132130
catch (URISyntaxException ex) {
133131
MalformedURLException exToThrow = new MalformedURLException(ex.getMessage());
@@ -144,17 +142,34 @@ public UrlResource(String protocol, String location, @Nullable String fragment)
144142
* @return the cleaned URL
145143
* @see org.springframework.util.StringUtils#cleanPath
146144
*/
147-
private URL getCleanedUrl(URL originalUrl, String originalPath) {
148-
try {
149-
return new URL(StringUtils.cleanPath(originalPath));
145+
private static URL getCleanedUrl(URL originalUrl, String originalPath) {
146+
String cleanedPath = StringUtils.cleanPath(originalPath);
147+
if (!cleanedPath.equals(originalPath)) {
148+
try {
149+
return new URL(cleanedPath);
150+
}
151+
catch (MalformedURLException ex) {
152+
// Cleaned URL path cannot be converted to URL -> take original URL.
153+
}
150154
}
151-
catch (MalformedURLException ex) {
152-
// Cleaned URL path cannot be converted to URL
153-
// -> take original URL.
154-
return originalUrl;
155+
return originalUrl;
156+
}
157+
158+
/**
159+
* Lazily determine a cleaned URL for the given original URL.
160+
* @see #getCleanedUrl(URL, String)
161+
*/
162+
private URL getCleanedUrl() {
163+
URL cleanedUrl = this.cleanedUrl;
164+
if (cleanedUrl != null) {
165+
return cleanedUrl;
155166
}
167+
cleanedUrl = getCleanedUrl(this.url, (this.uri != null ? this.uri : this.url).toString());
168+
this.cleanedUrl = cleanedUrl;
169+
return cleanedUrl;
156170
}
157171

172+
158173
/**
159174
* This implementation opens an InputStream for the given URL.
160175
* <p>It sets the {@code useCaches} flag to {@code false},
@@ -245,7 +260,7 @@ public Resource createRelative(String relativePath) throws MalformedURLException
245260
*/
246261
@Override
247262
public String getFilename() {
248-
return StringUtils.getFilename(this.cleanedUrl.getPath());
263+
return StringUtils.getFilename(getCleanedUrl().getPath());
249264
}
250265

251266
/**
@@ -263,15 +278,15 @@ public String getDescription() {
263278
@Override
264279
public boolean equals(Object other) {
265280
return (this == other || (other instanceof UrlResource &&
266-
this.cleanedUrl.equals(((UrlResource) other).cleanedUrl)));
281+
getCleanedUrl().equals(((UrlResource) other).getCleanedUrl())));
267282
}
268283

269284
/**
270285
* This implementation returns the hash code of the underlying URL reference.
271286
*/
272287
@Override
273288
public int hashCode() {
274-
return this.cleanedUrl.hashCode();
289+
return getCleanedUrl().hashCode();
275290
}
276291

277292
}

0 commit comments

Comments
 (0)