Skip to content

Commit 3be35c0

Browse files
committed
Use LinkedHashmap to preserve insert order
In several places in the spring-webmvc module, URL patterns / objects relationships are kept in `HashMap`s. When matching with actual URLs, the algorithm uses a pattern comparator to sort the matching patterns and select the most specific. But the underlying collection implementation does not keep the original order which can lead to inconsistencies. This commit changes the underlying collection implementation to `LinkedHashmap`s, in order to keep the insert order if the comparator does not reorder entries. Issue: SPR-13798
1 parent 5d454d5 commit 3be35c0

File tree

3 files changed

+14
-13
lines changed

3 files changed

+14
-13
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleUrlHandlerMapping.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
package org.springframework.web.servlet.handler;
1818

19-
import java.util.HashMap;
19+
import java.util.LinkedHashMap;
2020
import java.util.Map;
2121
import java.util.Properties;
2222

@@ -55,7 +55,7 @@
5555
*/
5656
public class SimpleUrlHandlerMapping extends AbstractUrlHandlerMapping {
5757

58-
private final Map<String, Object> urlMap = new HashMap<String, Object>();
58+
private final Map<String, Object> urlMap = new LinkedHashMap<String, Object>();
5959

6060

6161
/**

spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import java.util.ArrayList;
2020
import java.util.Collections;
2121
import java.util.Comparator;
22-
import java.util.HashMap;
22+
import java.util.LinkedHashMap;
2323
import java.util.List;
2424
import java.util.Map;
2525
import javax.servlet.http.HttpServletRequest;
@@ -55,7 +55,7 @@ public class ResourceUrlProvider implements ApplicationListener<ContextRefreshed
5555

5656
private PathMatcher pathMatcher = new AntPathMatcher();
5757

58-
private final Map<String, ResourceHttpRequestHandler> handlerMap = new HashMap<String, ResourceHttpRequestHandler>();
58+
private final Map<String, ResourceHttpRequestHandler> handlerMap = new LinkedHashMap<String, ResourceHttpRequestHandler>();
5959

6060
private boolean autodetect = true;
6161

spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@
1919
import java.util.ArrayList;
2020
import java.util.Collections;
2121
import java.util.Comparator;
22-
import java.util.HashMap;
22+
import java.util.LinkedHashMap;
2323
import java.util.List;
2424
import java.util.Map;
25+
2526
import javax.servlet.http.HttpServletRequest;
2627

2728
import org.springframework.core.io.Resource;
@@ -60,7 +61,7 @@ public class VersionResourceResolver extends AbstractResourceResolver {
6061
private AntPathMatcher pathMatcher = new AntPathMatcher();
6162

6263
/** Map from path pattern -> VersionStrategy */
63-
private final Map<String, VersionStrategy> versionStrategyMap = new HashMap<String, VersionStrategy>();
64+
private final Map<String, VersionStrategy> versionStrategyMap = new LinkedHashMap<String, VersionStrategy>();
6465

6566

6667
/**
@@ -209,17 +210,17 @@ protected String resolveUrlPathInternal(String resourceUrlPath, List<? extends R
209210
*/
210211
protected VersionStrategy getStrategyForPath(String requestPath) {
211212
String path = "/".concat(requestPath);
212-
List<String> matchingPatterns = new ArrayList<String>();
213+
List<String> matchingPatterns = new ArrayList<String>();
213214
for (String pattern : this.versionStrategyMap.keySet()) {
214215
if (this.pathMatcher.match(pattern, path)) {
215-
matchingPatterns.add(pattern);
216+
matchingPatterns.add(pattern);
216217
}
217218
}
218-
if (!matchingPatterns.isEmpty()) {
219-
Comparator<String> comparator = this.pathMatcher.getPatternComparator(path);
220-
Collections.sort(matchingPatterns, comparator);
221-
return this.versionStrategyMap.get(matchingPatterns.get(0));
222-
}
219+
if (!matchingPatterns.isEmpty()) {
220+
Comparator<String> comparator = this.pathMatcher.getPatternComparator(path);
221+
Collections.sort(matchingPatterns, comparator);
222+
return this.versionStrategyMap.get(matchingPatterns.get(0));
223+
}
223224
return null;
224225
}
225226

0 commit comments

Comments
 (0)