From d14eab844610ab488d0b266df6ac6f2630a62114 Mon Sep 17 00:00:00 2001 From: Norman Schimmrich <77899108+nschimmrich@users.noreply.github.com> Date: Thu, 10 Oct 2024 07:41:55 +0200 Subject: [PATCH] [kotlin-client][jvm-spring-webclient] Extract data from PartConfig for multipart/form-data requests (#19811) --- .../infrastructure/ApiClient.kt.mustache | 21 +++++++++++++++++-- .../client/infrastructure/ApiClient.kt | 21 +++++++++++++++++-- .../client/infrastructure/ApiClient.kt | 21 +++++++++++++++++-- .../client/infrastructure/ApiClient.kt | 21 +++++++++++++++++-- 4 files changed, 76 insertions(+), 8 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-spring-webclient/infrastructure/ApiClient.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-spring-webclient/infrastructure/ApiClient.kt.mustache index 3042e1aecea..3e54c65f099 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-spring-webclient/infrastructure/ApiClient.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-spring-webclient/infrastructure/ApiClient.kt.mustache @@ -6,6 +6,7 @@ import org.springframework.http.HttpMethod import org.springframework.http.MediaType import org.springframework.web.reactive.function.client.WebClient import org.springframework.http.ResponseEntity +import org.springframework.http.client.MultipartBodyBuilder import org.springframework.util.LinkedMultiValueMap import reactor.core.publisher.Mono @@ -47,8 +48,24 @@ open class ApiClient(protected val client: WebClient) { private fun WebClient.RequestBodySpec.headers(requestConfig: RequestConfig) = apply { requestConfig.headers.forEach { (name, value) -> header(name, value) } } - private fun WebClient.RequestBodySpec.body(requestConfig: RequestConfig) = - apply { if (requestConfig.body != null) bodyValue(requestConfig.body) } + private fun WebClient.RequestBodySpec.body(requestConfig: RequestConfig): WebClient.RequestBodySpec { + when { + requestConfig.headers[HttpHeaders.CONTENT_TYPE] == MediaType.MULTIPART_FORM_DATA_VALUE -> { + val builder = MultipartBodyBuilder() + (requestConfig.body as Map>).forEach { (name, part) -> + if (part.body != null) { + val partBuilder = builder.part(name, part.body) + val partHeaders = part.headers + partHeaders.forEach { partBuilder.header(it.key, it.value) } + } + } + return apply { bodyValue(builder.build()) } + } + else -> { + return apply { if (requestConfig.body != null) bodyValue(requestConfig.body) } + } + } + } } inline fun parseDateToQueryString(value : T): String { diff --git a/samples/client/echo_api/kotlin-jvm-spring-3-webclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/echo_api/kotlin-jvm-spring-3-webclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index b8acccd3de1..dd9cf519efc 100644 --- a/samples/client/echo_api/kotlin-jvm-spring-3-webclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/echo_api/kotlin-jvm-spring-3-webclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -6,6 +6,7 @@ import org.springframework.http.HttpMethod import org.springframework.http.MediaType import org.springframework.web.reactive.function.client.WebClient import org.springframework.http.ResponseEntity +import org.springframework.http.client.MultipartBodyBuilder import org.springframework.util.LinkedMultiValueMap import reactor.core.publisher.Mono @@ -47,8 +48,24 @@ open class ApiClient(protected val client: WebClient) { private fun WebClient.RequestBodySpec.headers(requestConfig: RequestConfig) = apply { requestConfig.headers.forEach { (name, value) -> header(name, value) } } - private fun WebClient.RequestBodySpec.body(requestConfig: RequestConfig) = - apply { if (requestConfig.body != null) bodyValue(requestConfig.body) } + private fun WebClient.RequestBodySpec.body(requestConfig: RequestConfig): WebClient.RequestBodySpec { + when { + requestConfig.headers[HttpHeaders.CONTENT_TYPE] == MediaType.MULTIPART_FORM_DATA_VALUE -> { + val builder = MultipartBodyBuilder() + (requestConfig.body as Map>).forEach { (name, part) -> + if (part.body != null) { + val partBuilder = builder.part(name, part.body) + val partHeaders = part.headers + partHeaders.forEach { partBuilder.header(it.key, it.value) } + } + } + return apply { bodyValue(builder.build()) } + } + else -> { + return apply { if (requestConfig.body != null) bodyValue(requestConfig.body) } + } + } + } } inline fun parseDateToQueryString(value : T): String { diff --git a/samples/client/petstore/kotlin-jvm-spring-2-webclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-jvm-spring-2-webclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index b8acccd3de1..dd9cf519efc 100644 --- a/samples/client/petstore/kotlin-jvm-spring-2-webclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-jvm-spring-2-webclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -6,6 +6,7 @@ import org.springframework.http.HttpMethod import org.springframework.http.MediaType import org.springframework.web.reactive.function.client.WebClient import org.springframework.http.ResponseEntity +import org.springframework.http.client.MultipartBodyBuilder import org.springframework.util.LinkedMultiValueMap import reactor.core.publisher.Mono @@ -47,8 +48,24 @@ open class ApiClient(protected val client: WebClient) { private fun WebClient.RequestBodySpec.headers(requestConfig: RequestConfig) = apply { requestConfig.headers.forEach { (name, value) -> header(name, value) } } - private fun WebClient.RequestBodySpec.body(requestConfig: RequestConfig) = - apply { if (requestConfig.body != null) bodyValue(requestConfig.body) } + private fun WebClient.RequestBodySpec.body(requestConfig: RequestConfig): WebClient.RequestBodySpec { + when { + requestConfig.headers[HttpHeaders.CONTENT_TYPE] == MediaType.MULTIPART_FORM_DATA_VALUE -> { + val builder = MultipartBodyBuilder() + (requestConfig.body as Map>).forEach { (name, part) -> + if (part.body != null) { + val partBuilder = builder.part(name, part.body) + val partHeaders = part.headers + partHeaders.forEach { partBuilder.header(it.key, it.value) } + } + } + return apply { bodyValue(builder.build()) } + } + else -> { + return apply { if (requestConfig.body != null) bodyValue(requestConfig.body) } + } + } + } } inline fun parseDateToQueryString(value : T): String { diff --git a/samples/client/petstore/kotlin-jvm-spring-3-webclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-jvm-spring-3-webclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index b8acccd3de1..dd9cf519efc 100644 --- a/samples/client/petstore/kotlin-jvm-spring-3-webclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-jvm-spring-3-webclient/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -6,6 +6,7 @@ import org.springframework.http.HttpMethod import org.springframework.http.MediaType import org.springframework.web.reactive.function.client.WebClient import org.springframework.http.ResponseEntity +import org.springframework.http.client.MultipartBodyBuilder import org.springframework.util.LinkedMultiValueMap import reactor.core.publisher.Mono @@ -47,8 +48,24 @@ open class ApiClient(protected val client: WebClient) { private fun WebClient.RequestBodySpec.headers(requestConfig: RequestConfig) = apply { requestConfig.headers.forEach { (name, value) -> header(name, value) } } - private fun WebClient.RequestBodySpec.body(requestConfig: RequestConfig) = - apply { if (requestConfig.body != null) bodyValue(requestConfig.body) } + private fun WebClient.RequestBodySpec.body(requestConfig: RequestConfig): WebClient.RequestBodySpec { + when { + requestConfig.headers[HttpHeaders.CONTENT_TYPE] == MediaType.MULTIPART_FORM_DATA_VALUE -> { + val builder = MultipartBodyBuilder() + (requestConfig.body as Map>).forEach { (name, part) -> + if (part.body != null) { + val partBuilder = builder.part(name, part.body) + val partHeaders = part.headers + partHeaders.forEach { partBuilder.header(it.key, it.value) } + } + } + return apply { bodyValue(builder.build()) } + } + else -> { + return apply { if (requestConfig.body != null) bodyValue(requestConfig.body) } + } + } + } } inline fun parseDateToQueryString(value : T): String {