Unverified Commit d356e571 by lowzj Committed by Spencer Gibb

update RequestParamParameterProcessor to support map param

fixes gh-1097
parent c5b0ffe3
...@@ -47,15 +47,18 @@ public class RequestParamParameterProcessor implements AnnotatedParameterProcess ...@@ -47,15 +47,18 @@ public class RequestParamParameterProcessor implements AnnotatedParameterProcess
Annotation annotation) { Annotation annotation) {
RequestParam requestParam = ANNOTATION.cast(annotation); RequestParam requestParam = ANNOTATION.cast(annotation);
String name = requestParam.value(); String name = requestParam.value();
checkState(emptyToNull(name) != null, if (emptyToNull(name) != null) {
"RequestParam.value() was empty on parameter %s",
context.getParameterIndex());
context.setParameterName(name); context.setParameterName(name);
MethodMetadata data = context.getMethodMetadata(); MethodMetadata data = context.getMethodMetadata();
Collection<String> query = context.setTemplateParameter(name, Collection<String> query = context.setTemplateParameter(name,
data.template().queries().get(name)); data.template().queries().get(name));
data.template().query(name, query); data.template().query(name, query);
} else {
// supports `Map` types
MethodMetadata data = context.getMethodMetadata();
data.queryMapIndex(context.getParameterIndex());
}
return true; return true;
} }
} }
...@@ -18,6 +18,7 @@ package org.springframework.cloud.netflix.feign.support; ...@@ -18,6 +18,7 @@ package org.springframework.cloud.netflix.feign.support;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
...@@ -27,6 +28,7 @@ import java.util.LinkedHashMap; ...@@ -27,6 +28,7 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.springframework.beans.BeanUtils;
import org.springframework.cloud.netflix.feign.AnnotatedParameterProcessor; import org.springframework.cloud.netflix.feign.AnnotatedParameterProcessor;
import org.springframework.cloud.netflix.feign.annotation.PathVariableParameterProcessor; import org.springframework.cloud.netflix.feign.annotation.PathVariableParameterProcessor;
import org.springframework.cloud.netflix.feign.annotation.RequestHeaderParameterProcessor; import org.springframework.cloud.netflix.feign.annotation.RequestHeaderParameterProcessor;
...@@ -313,8 +315,9 @@ public class SpringMvcContract extends Contract.BaseContract ...@@ -313,8 +315,9 @@ public class SpringMvcContract extends Contract.BaseContract
Object defaultValue = AnnotationUtils.getDefaultValue(parameterAnnotation); Object defaultValue = AnnotationUtils.getDefaultValue(parameterAnnotation);
if (defaultValue instanceof String if (defaultValue instanceof String
&& defaultValue.equals(annotationAttributes.get(AnnotationUtils.VALUE))) { && defaultValue.equals(annotationAttributes.get(AnnotationUtils.VALUE))) {
Type[] parameterTypes = method.getGenericParameterTypes();
String[] parameterNames = PARAMETER_NAME_DISCOVERER.getParameterNames(method); String[] parameterNames = PARAMETER_NAME_DISCOVERER.getParameterNames(method);
if (parameterNames != null && parameterNames.length > parameterIndex) { if (shouldAddParameterName(parameterIndex, parameterTypes, parameterNames)) {
annotationAttributes.put(AnnotationUtils.VALUE, annotationAttributes.put(AnnotationUtils.VALUE,
parameterNames[parameterIndex]); parameterNames[parameterIndex]);
} }
...@@ -323,6 +326,15 @@ public class SpringMvcContract extends Contract.BaseContract ...@@ -323,6 +326,15 @@ public class SpringMvcContract extends Contract.BaseContract
parameterAnnotation.annotationType(), null); parameterAnnotation.annotationType(), null);
} }
private boolean shouldAddParameterName(int parameterIndex, Type[] parameterTypes, String[] parameterNames) {
// has a parameter name
return parameterNames != null && parameterNames.length > parameterIndex
// has a type
&& parameterTypes != null && parameterTypes.length > parameterIndex
// and it is a simple property
&& BeanUtils.isSimpleProperty(parameterTypes[parameterIndex].getClass());
}
private class SimpleAnnotatedParameterContext private class SimpleAnnotatedParameterContext
implements AnnotatedParameterProcessor.AnnotatedParameterContext { implements AnnotatedParameterProcessor.AnnotatedParameterContext {
......
...@@ -19,6 +19,7 @@ package org.springframework.cloud.netflix.feign.support; ...@@ -19,6 +19,7 @@ package org.springframework.cloud.netflix.feign.support;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.List; import java.util.List;
import java.util.Map;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
...@@ -263,6 +264,19 @@ public class SpringMvcContractTests { ...@@ -263,6 +264,19 @@ public class SpringMvcContractTests {
} }
@Test @Test
public void testProcessAnnotations_MapParams() throws Exception {
Method method = TestTemplate_MapParams.class.getDeclaredMethod("getTest",
Map.class);
MethodMetadata data = this.contract
.parseAndValidateMetadata(method.getDeclaringClass(), method);
assertEquals("/test", data.template().url());
assertEquals("GET", data.template().method());
assertNotNull(data.queryMapIndex());
assertEquals(0, data.queryMapIndex().intValue());
}
@Test
public void testProcessHeaders() throws Exception { public void testProcessHeaders() throws Exception {
Method method = TestTemplate_Headers.class.getDeclaredMethod("getTest", Method method = TestTemplate_Headers.class.getDeclaredMethod("getTest",
String.class); String.class);
...@@ -279,7 +293,7 @@ public class SpringMvcContractTests { ...@@ -279,7 +293,7 @@ public class SpringMvcContractTests {
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTestFallback", Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTestFallback",
String.class, String.class, Integer.class); String.class, String.class, Integer.class);
assumeTrue(hasJava8ParameterNames(method)); assumeTrue("does not have java 8 parameter names", hasJava8ParameterNames(method));
MethodMetadata data = this.contract MethodMetadata data = this.contract
.parseAndValidateMetadata(method.getDeclaringClass(), method); .parseAndValidateMetadata(method.getDeclaringClass(), method);
...@@ -361,6 +375,11 @@ public class SpringMvcContractTests { ...@@ -361,6 +375,11 @@ public class SpringMvcContractTests {
ResponseEntity<TestObject> getTest(@RequestParam("id") List<String> id); ResponseEntity<TestObject> getTest(@RequestParam("id") List<String> id);
} }
public interface TestTemplate_MapParams {
@RequestMapping(value = "/test", method = RequestMethod.GET)
ResponseEntity<TestObject> getTest(@RequestParam Map<String, String> params);
}
@JsonAutoDetect @JsonAutoDetect
@RequestMapping("/advanced") @RequestMapping("/advanced")
public interface TestTemplate_Advanced { public interface TestTemplate_Advanced {
......
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