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
This commit is contained in:
Rossen Stoyanchev
2016-06-21 13:32:40 -04:00
parent db1092f119
commit 058279bc7e
2 changed files with 33 additions and 1 deletions

View File

@@ -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<RequestMapping
*/
@Override
public int compareTo(RequestMappingInfo other, HttpServletRequest request) {
int result = this.patternsCondition.compareTo(other.getPatternsCondition(), request);
int result;
// Automatic vs explicit HTTP HEAD mapping
if (HttpMethod.HEAD.matches(request.getMethod())) {
result = this.methodsCondition.compareTo(other.getMethodsCondition(), request);
if (result != 0) {
return result;
}
}
result = this.patternsCondition.compareTo(other.getPatternsCondition(), request);
if (result != 0) {
return result;
}
@@ -258,6 +267,7 @@ public final class RequestMappingInfo implements RequestCondition<RequestMapping
if (result != 0) {
return result;
}
// Implicit (no method) vs explicit HTTP method mappings
result = this.methodsCondition.compareTo(other.getMethodsCondition(), request);
if (result != 0) {
return result;