diff --git a/extensions/resteasy-reactive/jaxrs-client-reactive/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java b/extensions/resteasy-reactive/jaxrs-client-reactive/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java index 85b1fb98e769f6..133f34267c66ad 100644 --- a/extensions/resteasy-reactive/jaxrs-client-reactive/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java +++ b/extensions/resteasy-reactive/jaxrs-client-reactive/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java @@ -31,6 +31,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.concurrent.CompletionStage; @@ -2532,15 +2533,36 @@ private void addFormParam(BytecodeCreator methodCreator, String paramName, Resul notNullValue.load(methodIndex)); ResultHandle isString = notNullValue.instanceOf(convertedFormParam, String.class); BranchResult isStringBranch = notNullValue.ifTrue(isString); - isStringBranch.falseBranch().throwException(IllegalStateException.class, - "Form parameter '" + paramName - + "' could not be converted to 'String' for REST Client interface '" - + restClientInterfaceClassName + "'. A proper implementation of '" - + ParamConverter.class.getName() + "' needs to be returned by a '" - + ParamConverterProvider.class.getName() - + "' that is registered with the client via the @RegisterProvider annotation on the REST Client interface."); isStringBranch.trueBranch().invokeInterfaceMethod(MULTIVALUED_MAP_ADD, formParams, notNullValue.load(paramName), convertedFormParam); + + // if the converted value is not a string, then: + // - if it's a primitive type, use the valueOf() method. + if (EndpointIndexer.primitiveTypes.containsKey(parameterType)) { + ResultHandle convertedFormParamAsString = isStringBranch.falseBranch().invokeStaticMethod( + MethodDescriptor.ofMethod(Objects.class, "toString", String.class, Object.class), + convertedFormParam); + isStringBranch.falseBranch().invokeInterfaceMethod(MULTIVALUED_MAP_ADD, formParams, + notNullValue.load(paramName), convertedFormParamAsString); + } else { + // - if it's an enum, use the name() method. + ResultHandle isEnum = isStringBranch.falseBranch().instanceOf(convertedFormParam, Enum.class); + BranchResult isEnumBranch = isStringBranch.falseBranch().ifTrue(isEnum); + ResultHandle enumAsString = isEnumBranch.trueBranch().invokeVirtualMethod( + MethodDescriptor.ofMethod(parameterType, "name", String.class), + convertedFormParam); + isEnumBranch.trueBranch().invokeInterfaceMethod(MULTIVALUED_MAP_ADD, formParams, + notNullValue.load(paramName), enumAsString); + + // - Otherwise, return exception + isEnumBranch.falseBranch().throwException(IllegalStateException.class, + "Form parameter '" + paramName + + "' could not be converted to 'String' for REST Client interface '" + + restClientInterfaceClassName + "'. A proper implementation of '" + + ParamConverter.class.getName() + "' needs to be returned by a '" + + ParamConverterProvider.class.getName() + + "' that is registered with the client via the @RegisterProvider annotation on the REST Client interface."); + } } private void addCookieParam(BytecodeCreator invoBuilderEnricher, AssignableResultHandle invocationBuilder, diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/form/FormParamTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/form/FormParamTest.java index 06e44ca38a2196..fa8382cc0837e8 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/form/FormParamTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/form/FormParamTest.java @@ -24,7 +24,7 @@ public class FormParamTest { @RegisterExtension static final QuarkusUnitTest TEST = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(FormClient.class, SubFormClient.class, Resource.class)); + .addClasses(FormClient.class, SubFormClient.class, Resource.class, Mode.class)); @TestHTTPResource URI baseUri; @@ -50,6 +50,13 @@ void shouldPassFormParamFromSubResource() { assertThat(result).isEqualTo("sub rootParam1:par1,rootParam2:par 2,subParam1:spar1,subParam2:spar 2"); } + @Test + void shouldSupportParsingDifferentTypes() { + FormClient formClient = RestClientBuilder.newBuilder().baseUri(baseUri).build(FormClient.class); + String result = formClient.withTypes("a", 1, 2, Mode.On); + assertThat(result).isEqualTo("root text:a,number:1,wrapNumber:2,mode:On"); + } + public interface FormClient { @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @@ -58,6 +65,13 @@ public interface FormClient { @Path("/sub") SubFormClient subForm(@FormParam("rootParam1") String formParam1, @FormParam("rootParam2") String formParam2); + + @POST + @Path("/types") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.TEXT_PLAIN) + String withTypes(@FormParam("text") String text, @FormParam("number") int number, + @FormParam("wrapNumber") Integer wrapNumber, @FormParam("mode") Mode mode); } public interface SubFormClient { diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/form/Mode.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/form/Mode.java new file mode 100644 index 00000000000000..ab87072daf9289 --- /dev/null +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/form/Mode.java @@ -0,0 +1,6 @@ +package io.quarkus.rest.client.reactive.form; + +public enum Mode { + Off, + On +} diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/form/Resource.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/form/Resource.java index eb59b96008df82..43c6e134210dea 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/form/Resource.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/form/Resource.java @@ -30,4 +30,12 @@ public Response getUriEntityAndQueryParam(@RestForm String rootParam1, return Response.ok(String.format("sub rootParam1:%s,rootParam2:%s,subParam1:%s,subParam2:%s", rootParam1, rootParam2, subParam1, subParam2)).build(); } + + @POST + @Path("/types") + public Response getWithTypes(@RestForm String text, @RestForm int number, @RestForm Integer wrapNumber, + @RestForm Mode mode) { + return Response.ok(String.format("root text:%s,number:%s,wrapNumber:%s,mode:%s", text, number, wrapNumber, mode)) + .build(); + } }