From 3be35c053d14d4700f17b3ac4b27e06aa7c6d12e Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 16 Dec 2015 15:24:35 +0100 Subject: [PATCH] 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 --- .../handler/SimpleUrlHandlerMapping.java | 4 ++-- .../servlet/resource/ResourceUrlProvider.java | 4 ++-- .../resource/VersionResourceResolver.java | 19 ++++++++++--------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleUrlHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleUrlHandlerMapping.java index abef0a7ff7e..e34aa0b5a19 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleUrlHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleUrlHandlerMapping.java @@ -16,7 +16,7 @@ package org.springframework.web.servlet.handler; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; @@ -55,7 +55,7 @@ import org.springframework.util.CollectionUtils; */ public class SimpleUrlHandlerMapping extends AbstractUrlHandlerMapping { - private final Map urlMap = new HashMap(); + private final Map urlMap = new LinkedHashMap(); /** diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java index 13298ed8bbb..fbd2a55074f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java @@ -19,7 +19,7 @@ package org.springframework.web.servlet.resource; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; @@ -55,7 +55,7 @@ public class ResourceUrlProvider implements ApplicationListener handlerMap = new HashMap(); + private final Map handlerMap = new LinkedHashMap(); private boolean autodetect = true; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java index 939f8552335..5a06260766d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java @@ -19,9 +19,10 @@ package org.springframework.web.servlet.resource; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; + import javax.servlet.http.HttpServletRequest; import org.springframework.core.io.Resource; @@ -60,7 +61,7 @@ public class VersionResourceResolver extends AbstractResourceResolver { private AntPathMatcher pathMatcher = new AntPathMatcher(); /** Map from path pattern -> VersionStrategy */ - private final Map versionStrategyMap = new HashMap(); + private final Map versionStrategyMap = new LinkedHashMap(); /** @@ -209,17 +210,17 @@ public class VersionResourceResolver extends AbstractResourceResolver { */ protected VersionStrategy getStrategyForPath(String requestPath) { String path = "/".concat(requestPath); - List matchingPatterns = new ArrayList(); + List matchingPatterns = new ArrayList(); for (String pattern : this.versionStrategyMap.keySet()) { if (this.pathMatcher.match(pattern, path)) { - matchingPatterns.add(pattern); + matchingPatterns.add(pattern); } } - if (!matchingPatterns.isEmpty()) { - Comparator comparator = this.pathMatcher.getPatternComparator(path); - Collections.sort(matchingPatterns, comparator); - return this.versionStrategyMap.get(matchingPatterns.get(0)); - } + if (!matchingPatterns.isEmpty()) { + Comparator comparator = this.pathMatcher.getPatternComparator(path); + Collections.sort(matchingPatterns, comparator); + return this.versionStrategyMap.get(matchingPatterns.get(0)); + } return null; }