diff --git a/jaxrs/src/main/java/feign/jaxrs/JAXRSContract.java b/jaxrs/src/main/java/feign/jaxrs/JAXRSContract.java index da5fbec0..4c73af40 100644 --- a/jaxrs/src/main/java/feign/jaxrs/JAXRSContract.java +++ b/jaxrs/src/main/java/feign/jaxrs/JAXRSContract.java @@ -81,11 +81,9 @@ public final class JAXRSContract extends Contract.BaseContract { if (!methodAnnotationValue.startsWith("/") && !data.template().toString().endsWith("/")) { methodAnnotationValue = "/" + methodAnnotationValue; } - int regexIndex = methodAnnotationValue.indexOf(":"); - if (methodAnnotationValue.indexOf("{") != -1 && regexIndex != -1) { - // The method annotation includes a regex, which should be stripped to get the true path parameter name. - methodAnnotationValue = methodAnnotationValue.substring(0, regexIndex) + "}"; - } + // jax-rs allows whitespace around the param name, as well as an optional regex. The contract should + // strip these out appropriately. + methodAnnotationValue = methodAnnotationValue.replaceAll("\\{\\s*(.+?)\\s*(:.+?)?\\}", "\\{$1\\}"); data.template().append(methodAnnotationValue); } else if (annotationType == Produces.class) { String[] serverProduces = ((Produces) methodAnnotation).value(); diff --git a/jaxrs/src/test/java/feign/jaxrs/JAXRSContractTest.java b/jaxrs/src/test/java/feign/jaxrs/JAXRSContractTest.java index 84f6644f..75bb7e55 100644 --- a/jaxrs/src/test/java/feign/jaxrs/JAXRSContractTest.java +++ b/jaxrs/src/test/java/feign/jaxrs/JAXRSContractTest.java @@ -248,11 +248,22 @@ public class JAXRSContractTest { PathOnType.class.getDeclaredMethod("emptyPathParam", String.class)); } + @Test + public void pathParamWithSpaces() throws Exception { + assertThat(contract.parseAndValidatateMetadata( + PathOnType.class.getDeclaredMethod("pathParamWithSpaces", String.class)).template()) + .hasUrl("/base/{param}"); + } + @Test public void regexPathOnMethod() throws Exception { assertThat(contract.parseAndValidatateMetadata( PathOnType.class.getDeclaredMethod("pathParamWithRegex", String.class)).template()) .hasUrl("/base/regex/{param}"); + + assertThat(contract.parseAndValidatateMetadata( + PathOnType.class.getDeclaredMethod("pathParamWithMultipleRegex", String.class, String.class)).template()) + .hasUrl("/base/regex/{param1}/{param2}"); } @Test @@ -509,9 +520,17 @@ public class JAXRSContractTest { @Path("/{param}") Response emptyPathParam(@PathParam("") String empty); + @GET + @Path("/{ param }") + Response pathParamWithSpaces(@PathParam("param") String path); + @GET @Path("regex/{param:.+}") Response pathParamWithRegex(@PathParam("param") String path); + + @GET + @Path("regex/{param1:[0-9]*}/{ param2 : .+}") + Response pathParamWithMultipleRegex(@PathParam("param1") String param1, @PathParam("param2") String param2); } interface WithURIParam {