Browse Source

Support path parms in Class @RequestMapping for feign

This commit adds the support to SpringMvcContract for path parameters
defined in the class' @RequestMapping Annotation that is applied to all
methods of a feign interface.

fixes gh-1023
pull/6/head
Jacques-Etienne Beaudet 9 years ago committed by Spencer Gibb
parent
commit
726f355e9c
No known key found for this signature in database
GPG Key ID: 7788A47380690861
  1. 32
      spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringMvcContract.java
  2. 67
      spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringMvcContractTests.java

32
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringMvcContract.java

@ -106,6 +106,25 @@ public class SpringMvcContract extends Contract.BaseContract @@ -106,6 +106,25 @@ public class SpringMvcContract extends Contract.BaseContract
this.resourceLoader = resourceLoader;
}
@Override
protected void processAnnotationOnClass(MethodMetadata data, Class<?> clz) {
if (clz.getInterfaces().length == 0) {
RequestMapping classAnnotation = findMergedAnnotation(clz,
RequestMapping.class);
if (classAnnotation != null) {
// Prepend path from class annotation if specified
if (classAnnotation.value().length > 0) {
String pathValue = emptyToNull(classAnnotation.value()[0]);
pathValue = resolve(pathValue);
if (!pathValue.startsWith("/")) {
pathValue = "/" + pathValue;
}
data.template().insert(0, pathValue);
}
}
}
}
@Override
public MethodMetadata parseAndValidateMetadata(Class<?> targetType, Method method) {
this.processedMethods.put(Feign.configKey(targetType, method), method);
@ -114,19 +133,6 @@ public class SpringMvcContract extends Contract.BaseContract @@ -114,19 +133,6 @@ public class SpringMvcContract extends Contract.BaseContract
RequestMapping classAnnotation = findMergedAnnotation(targetType,
RequestMapping.class);
if (classAnnotation != null) {
// Prepend path from class annotation if specified
if (classAnnotation.value().length > 0) {
String pathValue = emptyToNull(classAnnotation.value()[0]);
checkState(pathValue != null,
"RequestMapping.value() was empty on type %s",
method.getDeclaringClass().getName());
pathValue = resolve(pathValue);
if (!pathValue.startsWith("/")) {
pathValue = "/" + pathValue;
}
md.template().insert(0, pathValue);
}
// produces - use from class annotation only if method has not specified this
if (!md.template().headers().containsKey(ACCEPT)) {
parseProduces(md, method, classAnnotation);

67
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringMvcContractTests.java

@ -34,14 +34,14 @@ import org.springframework.web.bind.annotation.RequestParam; @@ -34,14 +34,14 @@ import org.springframework.web.bind.annotation.RequestParam;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;
import feign.MethodMetadata;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.ToString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;
/**
* @author chadjaros
*/
@ -94,6 +94,53 @@ public class SpringMvcContractTests { @@ -94,6 +94,53 @@ public class SpringMvcContractTests {
assertEquals("id", data.indexToName().get(0).iterator().next());
}
@Test
public void testProcessAnnotations_Class_AnnotationsGetSpecificTest()
throws Exception {
Method method = TestTemplate_Class_Annotations.class.getDeclaredMethod(
"getSpecificTest", String.class, String.class);
MethodMetadata data = this.contract.parseAndValidateMetadata(
method.getDeclaringClass(), method);
assertEquals("/prepend/{classId}/test/{testId}", data.template().url());
assertEquals("GET", data.template().method());
assertEquals("classId", data.indexToName().get(0).iterator().next());
assertEquals("testId", data.indexToName().get(1).iterator().next());
}
@Test
public void testProcessAnnotations_Class_AnnotationsGetAllTests() throws Exception {
Method method = TestTemplate_Class_Annotations.class.getDeclaredMethod(
"getAllTests", String.class);
MethodMetadata data = this.contract.parseAndValidateMetadata(
method.getDeclaringClass(), method);
assertEquals("/prepend/{classId}", data.template().url());
assertEquals("GET", data.template().method());
assertEquals("classId", data.indexToName().get(0).iterator().next());
}
@Test
public void testProcessAnnotations_ExtendedInterface() throws Exception {
Method extendedMethod = TestTemplate_Extended.class.getMethod("getAllTests",
String.class);
MethodMetadata extendedData = this.contract.parseAndValidateMetadata(
extendedMethod.getDeclaringClass(), extendedMethod);
Method method = TestTemplate_Class_Annotations.class.getDeclaredMethod(
"getAllTests", String.class);
MethodMetadata data = this.contract.parseAndValidateMetadata(
method.getDeclaringClass(), method);
assertEquals(extendedData.template().url(), data.template().url());
assertEquals(extendedData.template().method(), data.template().method());
assertEquals(data.indexToName().get(0).iterator().next(),
data.indexToName().get(0).iterator().next());
}
@Test
public void testProcessAnnotations_SimplePost() throws Exception {
Method method = TestTemplate_Simple.class.getDeclaredMethod("postTest",
@ -273,6 +320,20 @@ public class SpringMvcContractTests { @@ -273,6 +320,20 @@ public class SpringMvcContractTests {
TestObject postTest(@RequestBody TestObject object);
}
@RequestMapping("/prepend/{classId}")
public interface TestTemplate_Class_Annotations {
@RequestMapping(value = "/test/{testId}", method = RequestMethod.GET)
TestObject getSpecificTest(@PathVariable("classId") String classId,
@PathVariable("testId") String testId);
@RequestMapping(method = RequestMethod.GET)
TestObject getAllTests(@PathVariable("classId") String classId);
}
public interface TestTemplate_Extended extends TestTemplate_Class_Annotations {
}
public interface TestTemplate_Headers {
@RequestMapping(value = "/test/{id}", method = RequestMethod.GET, headers = "X-Foo=bar")
ResponseEntity<TestObject> getTest(@PathVariable("id") String id);

Loading…
Cancel
Save