diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringMvcContract.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringMvcContract.java index 6c4b9138..6b9d91ed 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringMvcContract.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringMvcContract.java @@ -36,14 +36,14 @@ import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.Assert; import org.springframework.web.bind.annotation.RequestMapping; -import feign.Contract; -import feign.Feign; -import feign.MethodMetadata; - import static feign.Util.checkState; import static feign.Util.emptyToNull; import static org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation; +import feign.Contract; +import feign.Feign; +import feign.MethodMetadata; + /** * @author Spencer Gibb */ @@ -79,10 +79,11 @@ public class SpringMvcContract extends Contract.BaseContract { @Override public MethodMetadata parseAndValidateMetadata(Class targetType, Method method) { - processedMethods.put(Feign.configKey(targetType, method), method); + this.processedMethods.put(Feign.configKey(targetType, method), method); MethodMetadata md = super.parseAndValidateMetadata(targetType, method); - RequestMapping classAnnotation = findMergedAnnotation(targetType, RequestMapping.class); + RequestMapping classAnnotation = findMergedAnnotation(targetType, + RequestMapping.class); if (classAnnotation != null) { // Prepend path from class annotation if specified if (classAnnotation.value().length > 0) { @@ -169,7 +170,7 @@ public class SpringMvcContract extends Contract.BaseContract { AnnotatedParameterProcessor.AnnotatedParameterContext context = new SimpleAnnotatedParameterContext( data, paramIndex); - Method method = processedMethods.get(data.configKey()); + Method method = this.processedMethods.get(data.configKey()); for (Annotation parameterAnnotation : annotations) { AnnotatedParameterProcessor processor = this.annotatedArgumentProcessors .get(parameterAnnotation.annotationType()); @@ -213,9 +214,9 @@ public class SpringMvcContract extends Contract.BaseContract { // TODO: only supports one header value per key if (annotation.headers() != null && annotation.headers().length > 0) { for (String header : annotation.headers()) { - int colon = header.indexOf(':'); - md.template().header(header.substring(0, colon), - header.substring(colon + 2)); + int index = header.indexOf('='); + md.template().header(header.substring(0, index), + header.substring(index + 1).trim()); } } } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringMvcContractTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringMvcContractTests.java index fde15e62..edf0fd00 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringMvcContractTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringMvcContractTests.java @@ -182,6 +182,18 @@ public class SpringMvcContractTests { data.template().headers().get("Accept").iterator().next()); } + @Test + public void testProcessHeaders() throws Exception { + Method method = TestTemplate_Headers.class.getDeclaredMethod("getTest", + String.class); + MethodMetadata data = this.contract + .parseAndValidateMetadata(method.getDeclaringClass(), method); + + assertEquals("/test/{id}", data.template().url()); + assertEquals("GET", data.template().method()); + assertEquals("bar", data.template().headers().get("X-Foo").iterator().next()); + } + @Test public void testProcessAnnotations_Fallback() throws Exception { Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTestFallback", @@ -219,10 +231,12 @@ public class SpringMvcContractTests { org.springframework.util.Assert.isTrue(m.getParameterTypes().length > 0, "method has no parameters"); if (EXECUTABLE_TYPE != null) { - Method getParameters = ReflectionUtils.findMethod(EXECUTABLE_TYPE, "getParameters"); + Method getParameters = ReflectionUtils.findMethod(EXECUTABLE_TYPE, + "getParameters"); try { Object[] parameters = (Object[]) getParameters.invoke(m); - Method isNamePresent = ReflectionUtils.findMethod(parameters[0].getClass(), "isNamePresent"); + Method isNamePresent = ReflectionUtils + .findMethod(parameters[0].getClass(), "isNamePresent"); return Boolean.TRUE.equals(isNamePresent.invoke(parameters[0])); } catch (IllegalAccessException | IllegalArgumentException @@ -243,6 +257,11 @@ public class SpringMvcContractTests { TestObject postTest(@RequestBody TestObject object); } + public interface TestTemplate_Headers { + @RequestMapping(value = "/test/{id}", method = RequestMethod.GET, headers = "X-Foo=bar") + ResponseEntity getTest(@PathVariable("id") String id); + } + @JsonAutoDetect @RequestMapping("/advanced") public interface TestTemplate_Advanced { @@ -253,7 +272,8 @@ public class SpringMvcContractTests { @PathVariable("id") String id, @RequestParam("amount") Integer amount); @RequestMapping(path = "/test2", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE) - ResponseEntity getTest2(@RequestHeader(name = "Authorization") String auth, + ResponseEntity getTest2( + @RequestHeader(name = "Authorization") String auth, @RequestParam(name = "amount") Integer amount); @ExceptionHandler