|
18 | 18 |
|
19 | 19 | import java.util.ArrayList;
|
20 | 20 | import java.util.Collections;
|
| 21 | +import java.util.Comparator; |
21 | 22 | import java.util.HashMap;
|
22 | 23 | import java.util.List;
|
23 | 24 | import java.util.Map;
|
@@ -191,32 +192,41 @@ private int getLookupPathIndex(HttpServletRequest request) {
|
191 | 192 | * public use.
|
192 | 193 | * <p>It is expected that the given path is what Spring MVC would use for
|
193 | 194 | * request mapping purposes, i.e. excluding context and servlet path portions.
|
| 195 | + * <p>If several handler mappings match, the handler used will be the one |
| 196 | + * configured with the most specific pattern. |
194 | 197 | * @param lookupPath the lookup path to check
|
195 | 198 | * @return the resolved public URL path, or {@code null} if unresolved
|
196 | 199 | */
|
197 | 200 | public final String getForLookupPath(String lookupPath) {
|
198 | 201 | if (logger.isTraceEnabled()) {
|
199 | 202 | logger.trace("Getting resource URL for lookupPath=" + lookupPath);
|
200 | 203 | }
|
| 204 | + List<String> matchingPatterns = new ArrayList<String>(); |
201 | 205 | for (String pattern : this.handlerMap.keySet()) {
|
202 |
| - if (!getPathMatcher().match(pattern, lookupPath)) { |
203 |
| - continue; |
| 206 | + if (getPathMatcher().match(pattern, lookupPath)) { |
| 207 | + matchingPatterns.add(pattern); |
204 | 208 | }
|
205 |
| - String pathWithinMapping = getPathMatcher().extractPathWithinPattern(pattern, lookupPath); |
206 |
| - String pathMapping = lookupPath.substring(0, lookupPath.indexOf(pathWithinMapping)); |
207 |
| - if (logger.isTraceEnabled()) { |
208 |
| - logger.trace("Invoking ResourceResolverChain for URL pattern=\"" + pattern + "\""); |
209 |
| - } |
210 |
| - ResourceHttpRequestHandler handler = this.handlerMap.get(pattern); |
211 |
| - ResourceResolverChain chain = new DefaultResourceResolverChain(handler.getResourceResolvers()); |
212 |
| - String resolved = chain.resolveUrlPath(pathWithinMapping, handler.getLocations()); |
213 |
| - if (resolved == null) { |
214 |
| - continue; |
215 |
| - } |
216 |
| - if (logger.isTraceEnabled()) { |
217 |
| - logger.trace("Resolved public resource URL path=\"" + resolved + "\""); |
| 209 | + } |
| 210 | + if (!matchingPatterns.isEmpty()) { |
| 211 | + Comparator<String> patternComparator = getPathMatcher().getPatternComparator(lookupPath); |
| 212 | + Collections.sort(matchingPatterns, patternComparator); |
| 213 | + for(String pattern : matchingPatterns) { |
| 214 | + String pathWithinMapping = getPathMatcher().extractPathWithinPattern(pattern, lookupPath); |
| 215 | + String pathMapping = lookupPath.substring(0, lookupPath.indexOf(pathWithinMapping)); |
| 216 | + if (logger.isTraceEnabled()) { |
| 217 | + logger.trace("Invoking ResourceResolverChain for URL pattern=\"" + pattern + "\""); |
| 218 | + } |
| 219 | + ResourceHttpRequestHandler handler = this.handlerMap.get(pattern); |
| 220 | + ResourceResolverChain chain = new DefaultResourceResolverChain(handler.getResourceResolvers()); |
| 221 | + String resolved = chain.resolveUrlPath(pathWithinMapping, handler.getLocations()); |
| 222 | + if (resolved == null) { |
| 223 | + continue; |
| 224 | + } |
| 225 | + if (logger.isTraceEnabled()) { |
| 226 | + logger.trace("Resolved public resource URL path=\"" + resolved + "\""); |
| 227 | + } |
| 228 | + return pathMapping + resolved; |
218 | 229 | }
|
219 |
| - return pathMapping + resolved; |
220 | 230 | }
|
221 | 231 | logger.debug("No matching resource mapping");
|
222 | 232 | return null;
|
|
0 commit comments