From 7cdcc102a9bf36245b5af95acfa3c62d3777b16d Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Sun, 17 Apr 2016 15:12:43 -0400 Subject: [PATCH] Explicit HEAD sorted higher than implicit GET match Issue: SPR-14182 --- .../RequestMethodsRequestCondition.java | 19 ++++++++++++---- .../RequestMethodsRequestConditionTests.java | 2 +- ...nnotationControllerHandlerMethodTests.java | 22 +++++++++++++++++++ 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestCondition.java index a8f67d3a5815..b0dd93d795b8 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestCondition.java @@ -39,8 +39,8 @@ */ public final class RequestMethodsRequestCondition extends AbstractRequestCondition { - private static final RequestMethodsRequestCondition HEAD_CONDITION = - new RequestMethodsRequestCondition(RequestMethod.HEAD); + private static final RequestMethodsRequestCondition GET_CONDITION = + new RequestMethodsRequestCondition(RequestMethod.GET); private final Set methods; @@ -140,7 +140,7 @@ private RequestMethodsRequestCondition matchRequestMethod(String httpMethodValue } } if (httpMethod == HttpMethod.HEAD && getMethods().contains(RequestMethod.GET)) { - return HEAD_CONDITION; + return GET_CONDITION; } } return null; @@ -159,7 +159,18 @@ private RequestMethodsRequestCondition matchRequestMethod(String httpMethodValue */ @Override public int compareTo(RequestMethodsRequestCondition other, HttpServletRequest request) { - return (other.methods.size() - this.methods.size()); + if (other.methods.size() != this.methods.size()) { + return other.methods.size() - this.methods.size(); + } + else if (this.methods.size() == 1) { + if (this.methods.contains(RequestMethod.HEAD) && other.methods.contains(RequestMethod.GET)) { + return -1; + } + else if (this.methods.contains(RequestMethod.GET) && other.methods.contains(RequestMethod.HEAD)) { + return 1; + } + } + return 0; } } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestConditionTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestConditionTests.java index 10503065c2bb..df336a3c32e1 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestConditionTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestConditionTests.java @@ -53,7 +53,7 @@ public void getMatchingCondition() { @Test public void getMatchingConditionWithHttpHead() { testMatch(new RequestMethodsRequestCondition(HEAD), HEAD); - testMatch(new RequestMethodsRequestCondition(GET), HEAD); + testMatch(new RequestMethodsRequestCondition(GET), GET); testNoMatch(new RequestMethodsRequestCondition(POST), HEAD); } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletAnnotationControllerHandlerMethodTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletAnnotationControllerHandlerMethodTests.java index 24d9ea2c05ec..48163090a75f 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletAnnotationControllerHandlerMethodTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletAnnotationControllerHandlerMethodTests.java @@ -1776,6 +1776,18 @@ public void httpHead() throws ServletException, IOException { assertEquals("body", response.getContentAsString()); } + @Test + public void httpHeadExplicit() throws ServletException, IOException { + initServletWithControllers(ResponseEntityController.class); + + MockHttpServletRequest request = new MockHttpServletRequest("HEAD", "/stores"); + MockHttpServletResponse response = new MockHttpServletResponse(); + getServlet().service(request, response); + + assertEquals(200, response.getStatus()); + assertEquals("v1", response.getHeader("h1")); + } + @Test public void httpOptions() throws ServletException, IOException { initServletWithControllers(ResponseEntityController.class); @@ -3100,6 +3112,16 @@ public ResponseEntity bar() { public ResponseEntity baz() { return ResponseEntity.ok().header("MyResponseHeader", "MyValue").body("body"); } + + @RequestMapping(path = "/stores", method = RequestMethod.HEAD) + public ResponseEntity headResource() { + return ResponseEntity.ok().header("h1", "v1").build(); + } + + @RequestMapping(path = "/stores", method = RequestMethod.GET) + public ResponseEntity getResource() { + return ResponseEntity.ok().body("body"); + } } @Controller