Commit 2c502e39 by Jacques-Etienne Beaudet Committed by Dave Syer

Add support in SpringMvcContract for query string in Class @RequestMapping

This commit adds the support for query string defined in the class' @RequestMapping Annotation that is applied to all method of a controller. Fxies gh-1023, fixes gh-1024
parent 32d481df
...@@ -107,26 +107,33 @@ public class SpringMvcContract extends Contract.BaseContract ...@@ -107,26 +107,33 @@ public class SpringMvcContract extends Contract.BaseContract
} }
@Override @Override
public MethodMetadata parseAndValidateMetadata(Class<?> targetType, Method method) { protected void processAnnotationOnClass(MethodMetadata data, Class<?> clz) {
this.processedMethods.put(Feign.configKey(targetType, method), method); if(clz.getInterfaces().length == 0) {
MethodMetadata md = super.parseAndValidateMetadata(targetType, method); RequestMapping classAnnotation = findMergedAnnotation(clz,
RequestMapping classAnnotation = findMergedAnnotation(targetType,
RequestMapping.class); RequestMapping.class);
if (classAnnotation != null) { if (classAnnotation != null) {
// Prepend path from class annotation if specified // Prepend path from class annotation if specified
if (classAnnotation.value().length > 0) { if (classAnnotation.value().length > 0) {
String pathValue = emptyToNull(classAnnotation.value()[0]); String pathValue = emptyToNull(classAnnotation.value()[0]);
checkState(pathValue != null,
"RequestMapping.value() was empty on type %s",
method.getDeclaringClass().getName());
pathValue = resolve(pathValue); pathValue = resolve(pathValue);
if (!pathValue.startsWith("/")) { if (!pathValue.startsWith("/")) {
pathValue = "/" + pathValue; pathValue = "/" + pathValue;
} }
md.template().insert(0, pathValue); data.template().insert(0, pathValue);
} }
}
}
}
@Override
public MethodMetadata parseAndValidateMetadata(Class<?> targetType, Method method) {
this.processedMethods.put(Feign.configKey(targetType, method), method);
MethodMetadata md = super.parseAndValidateMetadata(targetType, method);
RequestMapping classAnnotation = findMergedAnnotation(targetType,
RequestMapping.class);
if (classAnnotation != null) {
// produces - use from class annotation only if method has not specified this // produces - use from class annotation only if method has not specified this
if (!md.template().headers().containsKey(ACCEPT)) { if (!md.template().headers().containsKey(ACCEPT)) {
parseProduces(md, method, classAnnotation); parseProduces(md, method, classAnnotation);
......
...@@ -72,39 +72,51 @@ public class SpringMvcContractTests { ...@@ -72,39 +72,51 @@ public class SpringMvcContractTests {
String.class); String.class);
MethodMetadata data = this.contract MethodMetadata data = this.contract
.parseAndValidateMetadata(method.getDeclaringClass(), method); .parseAndValidateMetadata(method.getDeclaringClass(), method);
MethodMetadata extendingData = this.contract
.parseAndValidateMetadata(method.getDeclaringClass(), method);
assertEquals("/test/{id}", data.template().url()); assertEquals("/prepend/{anotherId}", data.template().url());
assertEquals(data.template().url(), extendingData.template().url());
assertEquals("GET", data.template().method()); assertEquals("GET", data.template().method());
assertEquals(data.template().method(), extendingData.template().method());
assertEquals(MediaType.APPLICATION_JSON_VALUE, assertEquals(MediaType.APPLICATION_JSON_VALUE,
data.template().headers().get("Accept").iterator().next()); data.template().headers().get("Accept").iterator().next());
assertEquals(data.template().headers().get("Accept").iterator().next(),
extendingData.template().headers().get("Accept").iterator().next());
assertEquals("anotherId", data.indexToName().get(0).iterator().next());
assertEquals(data.indexToName().get(0).iterator().next(),
extendingData.indexToName().get(0).iterator().next());
} }
@Test @Test
public void testProcessAnnotations_Simple() throws Exception { public void testProcessAnnotations_Simple() throws Exception {
Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest", Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest",
String.class); String.class, String.class);
MethodMetadata data = this.contract MethodMetadata data = this.contract
.parseAndValidateMetadata(method.getDeclaringClass(), method); .parseAndValidateMetadata(method.getDeclaringClass(), method);
assertEquals("/test/{id}", data.template().url()); assertEquals("/prepend/{anotherId}/test/{id}", data.template().url());
assertEquals("GET", data.template().method()); assertEquals("GET", data.template().method());
assertEquals(MediaType.APPLICATION_JSON_VALUE, assertEquals(MediaType.APPLICATION_JSON_VALUE,
data.template().headers().get("Accept").iterator().next()); data.template().headers().get("Accept").iterator().next());
assertEquals("id", data.indexToName().get(0).iterator().next()); assertEquals("anotherId", data.indexToName().get(0).iterator().next());
assertEquals("id", data.indexToName().get(1).iterator().next());
} }
@Test @Test
public void testProcessAnnotations_SimplePost() throws Exception { public void testProcessAnnotations_SimplePost() throws Exception {
Method method = TestTemplate_Simple.class.getDeclaredMethod("postTest", Method method = TestTemplate_Simple.class.getDeclaredMethod("postTest",
TestObject.class); String.class, TestObject.class);
MethodMetadata data = this.contract MethodMetadata data = this.contract
.parseAndValidateMetadata(method.getDeclaringClass(), method); .parseAndValidateMetadata(method.getDeclaringClass(), method);
assertEquals("", data.template().url()); assertEquals("/prepend/{anotherId}", data.template().url());
assertEquals("POST", data.template().method()); assertEquals("POST", data.template().method());
assertEquals(MediaType.APPLICATION_JSON_VALUE, assertEquals(MediaType.APPLICATION_JSON_VALUE,
data.template().headers().get("Accept").iterator().next()); data.template().headers().get("Accept").iterator().next());
assertEquals("anotherId", data.indexToName().get(0).iterator().next());
} }
...@@ -188,14 +200,16 @@ public class SpringMvcContractTests { ...@@ -188,14 +200,16 @@ public class SpringMvcContractTests {
@Test @Test
public void testProcessAnnotations_Advanced3() throws Exception { public void testProcessAnnotations_Advanced3() throws Exception {
Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest"); Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest",
String.class);
MethodMetadata data = this.contract MethodMetadata data = this.contract
.parseAndValidateMetadata(method.getDeclaringClass(), method); .parseAndValidateMetadata(method.getDeclaringClass(), method);
assertEquals("", data.template().url()); assertEquals("/prepend/{anotherId}", data.template().url());
assertEquals("GET", data.template().method()); assertEquals("GET", data.template().method());
assertEquals(MediaType.APPLICATION_JSON_VALUE, assertEquals(MediaType.APPLICATION_JSON_VALUE,
data.template().headers().get("Accept").iterator().next()); data.template().headers().get("Accept").iterator().next());
assertEquals("anotherId", data.indexToName().get(0).iterator().next());
} }
@Test @Test
...@@ -262,15 +276,20 @@ public class SpringMvcContractTests { ...@@ -262,15 +276,20 @@ public class SpringMvcContractTests {
return false; return false;
} }
@RequestMapping("/prepend/{anotherId}")
public interface TestTemplate_Simple { public interface TestTemplate_Simple {
@RequestMapping(value = "/test/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(value = "/test/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<TestObject> getTest(@PathVariable("id") String id); ResponseEntity<TestObject> getTest(@PathVariable String anotherId, @PathVariable String id);
@RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
TestObject getTest(); TestObject getTest(@PathVariable String anotherId);
@RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
TestObject postTest(@RequestBody TestObject object); TestObject postTest(@PathVariable String anotherId, @RequestBody TestObject object);
}
public interface TestTemplate_Simple_Extending extends TestTemplate_Simple{
} }
public interface TestTemplate_Headers { public interface TestTemplate_Headers {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment