From 058279bc7ed0466c0106b62c6a3455f1f316cb0c Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 21 Jun 2016 13:32:40 -0400 Subject: [PATCH] HEAD mapping has higher priority over other conditions When comparing multiple matching @RequestMapping's, the HTTP method condition has the lowest precedence. It's mainly about ensuring an explicit mapping wins over an implicit (i.e. no method) one. As of 4.3 HTTP HEAD is handled automatically for controller methods that match to GET. However an explicit mapping HTTP HEAD allows an application to take control. This commit ensures that for HTTP HEAD requests the HTTP method condition is checked first which means that an explicit HEAD mapping now trumps all other conditions. Normally we look for the most specific matching @RequestMapping. For HTTP HEAD we now look for the most specific match among @RequestMapping methods with a HEAD mapping first. Issue: SPR-14383 --- .../mvc/method/RequestMappingInfo.java | 12 +++++++++- .../mvc/method/RequestMappingInfoTests.java | 22 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java index 445f55f5a8..a9cf31bb3e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java @@ -19,6 +19,7 @@ package org.springframework.web.servlet.mvc.method; import java.util.List; import javax.servlet.http.HttpServletRequest; +import org.springframework.http.HttpMethod; import org.springframework.util.PathMatcher; import org.springframework.util.StringUtils; import org.springframework.web.accept.ContentNegotiationManager; @@ -238,7 +239,15 @@ public final class RequestMappingInfo implements RequestCondition comparator = (info, otherInfo) -> info.compareTo(otherInfo, request); + + List list = asList(noMethods, getMethod, headMethod); + Collections.shuffle(list); + Collections.sort(list, comparator); + + assertEquals(headMethod, list.get(0)); + assertEquals(getMethod, list.get(1)); + assertEquals(noMethods, list.get(2)); + } + @Test public void equals() { RequestMappingInfo info1 = paths("/foo").methods(GET)