From c629408ab262978ce9d67dcef19a44ab900c3025 Mon Sep 17 00:00:00 2001 From: AlbertWaninge Date: Mon, 8 Dec 2025 11:03:14 +0100 Subject: [PATCH 1/3] #22339 fix query parameter encoding --- .../infrastructure/ApiClient.kt.mustache | 11 ++++++----- .../openapitools/client/infrastructure/ApiClient.kt | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-spring-restclient/infrastructure/ApiClient.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-spring-restclient/infrastructure/ApiClient.kt.mustache index c6d11989dcef..ab6f59125c05 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-spring-restclient/infrastructure/ApiClient.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-spring-restclient/infrastructure/ApiClient.kt.mustache @@ -35,12 +35,13 @@ import org.springframework.util.LinkedMultiValueMap private fun RestClient.method(requestConfig: RequestConfig)= method(HttpMethod.valueOf(requestConfig.method.name)) - private fun RestClient.RequestBodyUriSpec.uri(requestConfig: RequestConfig) = - uri(requestConfig.path) { builder -> - builder - .queryParams(LinkedMultiValueMap(requestConfig.query)) - .build(requestConfig.params) + private fun RestClient.RequestBodyUriSpec.uri(requestConfig: RequestConfig): RestClient.RequestBodySpec { + val uriComponentsBuilder = UriComponentsBuilder.fromPath(requestConfig.path) + requestConfig.query.forEach { key, values -> + uriComponentsBuilder.queryParam(key, "{$key}") } + return uri(uriComponentsBuilder.encode().buildAndExpand(requestConfig.query + requestConfig.params).toUri()) + } private fun RestClient.RequestBodySpec.headers(requestConfig: RequestConfig) = apply { requestConfig.headers.forEach { (name, value) -> header(name, value) } } diff --git a/samples/client/petstore/kotlin-jvm-spring-3-restclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-jvm-spring-3-restclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index d13aa82aab69..2ec4285680b9 100644 --- a/samples/client/petstore/kotlin-jvm-spring-3-restclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-jvm-spring-3-restclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -35,12 +35,13 @@ open class ApiClient(protected val client: RestClient) { private fun RestClient.method(requestConfig: RequestConfig)= method(HttpMethod.valueOf(requestConfig.method.name)) - private fun RestClient.RequestBodyUriSpec.uri(requestConfig: RequestConfig) = - uri(requestConfig.path) { builder -> - builder - .queryParams(LinkedMultiValueMap(requestConfig.query)) - .build(requestConfig.params) + private fun RestClient.RequestBodyUriSpec.uri(requestConfig: RequestConfig): RestClient.RequestBodySpec { + val uriComponentsBuilder = UriComponentsBuilder.fromPath(requestConfig.path) + requestConfig.query.forEach { key, values -> + uriComponentsBuilder.queryParam(key, "{$key}") } + return uri(uriComponentsBuilder.encode().buildAndExpand(requestConfig.query + requestConfig.params).toUri()) + } private fun RestClient.RequestBodySpec.headers(requestConfig: RequestConfig) = apply { requestConfig.headers.forEach { (name, value) -> header(name, value) } } From 9b1e40ec03f5a5b870336a620633f838ac371158 Mon Sep 17 00:00:00 2001 From: AlbertWaninge Date: Mon, 8 Dec 2025 13:49:08 +0100 Subject: [PATCH 2/3] #22339 fix query parameter encoding --- .../jvm-spring-restclient/infrastructure/ApiClient.kt.mustache | 3 ++- .../kotlin/org/openapitools/client/infrastructure/ApiClient.kt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-spring-restclient/infrastructure/ApiClient.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-spring-restclient/infrastructure/ApiClient.kt.mustache index ab6f59125c05..91463eaa179f 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-spring-restclient/infrastructure/ApiClient.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-spring-restclient/infrastructure/ApiClient.kt.mustache @@ -4,8 +4,9 @@ import org.springframework.core.ParameterizedTypeReference import org.springframework.http.HttpHeaders import org.springframework.http.HttpMethod import org.springframework.http.MediaType -import org.springframework.web.client.RestClient import org.springframework.http.ResponseEntity +import org.springframework.web.client.RestClient +import org.springframework.web.util.UriComponentsBuilder import org.springframework.util.LinkedMultiValueMap {{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}open class ApiClient(protected val client: RestClient) { diff --git a/samples/client/petstore/kotlin-jvm-spring-3-restclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-jvm-spring-3-restclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 2ec4285680b9..43287db8fc44 100644 --- a/samples/client/petstore/kotlin-jvm-spring-3-restclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-jvm-spring-3-restclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -4,8 +4,9 @@ import org.springframework.core.ParameterizedTypeReference import org.springframework.http.HttpHeaders import org.springframework.http.HttpMethod import org.springframework.http.MediaType -import org.springframework.web.client.RestClient import org.springframework.http.ResponseEntity +import org.springframework.web.client.RestClient +import org.springframework.web.util.UriComponentsBuilder import org.springframework.util.LinkedMultiValueMap open class ApiClient(protected val client: RestClient) { From 9e067597cb9de47e764dc03fca80e78e50993ca7 Mon Sep 17 00:00:00 2001 From: AlbertWaninge Date: Mon, 15 Dec 2025 16:18:42 +0100 Subject: [PATCH 3/3] #22339 ran generate-samples with some local adaptations --- .../client/infrastructure/ApiClient.kt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/samples/client/echo_api/kotlin-jvm-spring-3-restclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/echo_api/kotlin-jvm-spring-3-restclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index d13aa82aab69..43287db8fc44 100644 --- a/samples/client/echo_api/kotlin-jvm-spring-3-restclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/echo_api/kotlin-jvm-spring-3-restclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -4,8 +4,9 @@ import org.springframework.core.ParameterizedTypeReference import org.springframework.http.HttpHeaders import org.springframework.http.HttpMethod import org.springframework.http.MediaType -import org.springframework.web.client.RestClient import org.springframework.http.ResponseEntity +import org.springframework.web.client.RestClient +import org.springframework.web.util.UriComponentsBuilder import org.springframework.util.LinkedMultiValueMap open class ApiClient(protected val client: RestClient) { @@ -35,12 +36,13 @@ open class ApiClient(protected val client: RestClient) { private fun RestClient.method(requestConfig: RequestConfig)= method(HttpMethod.valueOf(requestConfig.method.name)) - private fun RestClient.RequestBodyUriSpec.uri(requestConfig: RequestConfig) = - uri(requestConfig.path) { builder -> - builder - .queryParams(LinkedMultiValueMap(requestConfig.query)) - .build(requestConfig.params) + private fun RestClient.RequestBodyUriSpec.uri(requestConfig: RequestConfig): RestClient.RequestBodySpec { + val uriComponentsBuilder = UriComponentsBuilder.fromPath(requestConfig.path) + requestConfig.query.forEach { key, values -> + uriComponentsBuilder.queryParam(key, "{$key}") } + return uri(uriComponentsBuilder.encode().buildAndExpand(requestConfig.query + requestConfig.params).toUri()) + } private fun RestClient.RequestBodySpec.headers(requestConfig: RequestConfig) = apply { requestConfig.headers.forEach { (name, value) -> header(name, value) } }