diff --git a/core/src/main/java/feign/Contract.java b/core/src/main/java/feign/Contract.java
index aff6a3b28..6c2741d65 100644
--- a/core/src/main/java/feign/Contract.java
+++ b/core/src/main/java/feign/Contract.java
@@ -271,7 +271,14 @@ public Default() {
data.template().headers(toMap(headersOnMethod));
});
super.registerParameterAnnotation(Param.class, (paramAnnotation, data, paramIndex) -> {
- final String name = paramAnnotation.value();
+ final String annotationName = paramAnnotation.value();
+ final Parameter parameter = data.method().getParameters()[paramIndex];
+ final String name;
+ if (emptyToNull(annotationName) == null && parameter.isNamePresent()){
+ name = parameter.getName();
+ } else {
+ name = annotationName;
+ }
checkState(emptyToNull(name) != null, "Param annotation was empty on param %s.",
paramIndex);
nameParam(data, name, paramIndex);
diff --git a/core/src/main/java/feign/Param.java b/core/src/main/java/feign/Param.java
index 27e968e8f..7501cc29f 100644
--- a/core/src/main/java/feign/Param.java
+++ b/core/src/main/java/feign/Param.java
@@ -28,7 +28,7 @@
/**
* The name of the template parameter.
*/
- String value();
+ String value() default "";
/**
* How to expand the value of this parameter, if {@link ToStringExpander} isn't adequate.
diff --git a/core/src/test/java/feign/DefaultContractTest.java b/core/src/test/java/feign/DefaultContractTest.java
index 33d1599fd..77c5d20ab 100644
--- a/core/src/test/java/feign/DefaultContractTest.java
+++ b/core/src/test/java/feign/DefaultContractTest.java
@@ -200,6 +200,21 @@ public void pathAndQueryParams() throws Exception {
entry(2, asList("type")));
}
+ @Test
+ public void autoDiscoverParamNames() throws Exception {
+ final MethodMetadata md = parseAndValidateMetadata(AutoDiscoverParamNames.class,
+ "recordsByNameAndType", int.class, String.class,
+ String.class);
+
+ assertThat(md.template())
+ .hasQueries(entry("name", asList("{name}")), entry("type", asList("{type}")));
+
+ assertThat(md.indexToName()).containsExactly(
+ entry(0, asList("domainId")),
+ entry(1, asList("name")),
+ entry(2, asList("type")));
+ }
+
@Test
public void bodyWithTemplate() throws Exception {
final MethodMetadata md = parseAndValidateMetadata(FormParams.class,
@@ -517,6 +532,12 @@ Response recordsByNameAndType(@Param("domainId") int id,
@Param("type") String typeFilter);
}
+ interface AutoDiscoverParamNames {
+
+ @RequestLine("GET /domains/{domainId}/records?name={name}&type={type}")
+ Response recordsByNameAndType(@Param int domainId, @Param String name, @Param() String type);
+}
+
interface FormParams {
@RequestLine("POST /")
diff --git a/pom.xml b/pom.xml
index 1432b121f..2f33d70a6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -417,6 +417,21 @@
${main.java.version}
+
+ default-test-compile
+ test-compile
+
+ testCompile
+
+
+ true
+
+ -parameters
+
+
+ ${main.java.version}
+
+