From 462d6897c3eafdbccc342042816eb4f41bfa76da Mon Sep 17 00:00:00 2001 From: Bruno Coelho <4brunu@gmail.com> Date: Thu, 10 Oct 2024 22:07:55 +0100 Subject: [PATCH 1/2] [kotlin] Map file and binary to ByteArray --- bin/configs/kotlin-string.yaml | 1 + .../codegen/languages/KotlinClientCodegen.java | 15 +++++++++++++++ .../infrastructure/ApiClient.kt.mustache | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/petstore/kotlin-string/docs/PetApi.md | 4 ++-- .../org/openapitools/client/apis/PetApi.kt | 6 +++--- .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ .../client/infrastructure/ApiClient.kt | 16 ++++++++++++++++ 25 files changed, 357 insertions(+), 5 deletions(-) diff --git a/bin/configs/kotlin-string.yaml b/bin/configs/kotlin-string.yaml index e6cd63e4b408..0af67a43e22a 100644 --- a/bin/configs/kotlin-string.yaml +++ b/bin/configs/kotlin-string.yaml @@ -5,6 +5,7 @@ templateDir: modules/openapi-generator/src/main/resources/kotlin-client additionalProperties: artifactId: kotlin-petstore-string serializableModel: "true" + mapFileBinaryToByteArray: "true" sortModelPropertiesByRequiredFlag: "false" sortParamsByRequiredFlag: "false" dateLibrary: string diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java index f6b48c7563b3..1310e2861912 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java @@ -93,10 +93,13 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen { public static final String SUPPORT_ANDROID_API_LEVEL_25_AND_BELLOW = "supportAndroidApiLevel25AndBelow"; + public static final String MAP_FILE_BINARY_TO_BYTE_ARRAY = "mapFileBinaryToByteArray"; + public static final String GENERATE_ONEOF_ANYOF_WRAPPERS = "generateOneOfAnyOfWrappers"; protected static final String VENDOR_EXTENSION_BASE_NAME_LITERAL = "x-base-name-literal"; + @Setter protected String dateLibrary = DateLibrary.JAVA8.value; @Setter protected String requestDateConverter = RequestDateConverter.TO_JSON.value; @Setter protected String collectionType = CollectionType.LIST.value; @@ -108,6 +111,7 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen { protected boolean generateRoomModels = false; @Setter protected String roomModelPackage = ""; @Setter protected boolean omitGradleWrapper = false; + @Setter protected boolean mapFileBinaryToByteArray = false; @Setter protected boolean generateOneOfAnyOfWrappers = true; @Getter @Setter protected boolean failOnUnknownProperties = false; @@ -269,6 +273,8 @@ public KotlinClientCodegen() { cliOptions.add(CliOption.newBoolean(SUPPORT_ANDROID_API_LEVEL_25_AND_BELLOW, "[WARNING] This flag will generate code that has a known security vulnerability. It uses `kotlin.io.createTempFile` instead of `java.nio.file.Files.createTempFile` in order to support Android API level 25 and bellow. For more info, please check the following links https://github.com/OpenAPITools/openapi-generator/security/advisories/GHSA-23x4-m842-fmwf, https://github.com/OpenAPITools/openapi-generator/pull/9284")); + cliOptions.add(new CliOption(MAP_FILE_BINARY_TO_BYTE_ARRAY, "Map File and Binary to ByteArray (default: false)").defaultValue(Boolean.FALSE.toString())); + cliOptions.add(CliOption.newBoolean(GENERATE_ONEOF_ANYOF_WRAPPERS, "Generate oneOf, anyOf schemas as wrappers.")); CliOption serializationLibraryOpt = new CliOption(CodegenConstants.SERIALIZATION_LIBRARY, SERIALIZATION_LIBRARY_DESC); @@ -437,6 +443,15 @@ public void processOpts() { additionalProperties.put(this.serializationLibrary.name(), true); } + if (additionalProperties.containsKey(MAP_FILE_BINARY_TO_BYTE_ARRAY)) { + setMapFileBinaryToByteArray(convertPropertyToBooleanAndWriteBack(MAP_FILE_BINARY_TO_BYTE_ARRAY)); + } + additionalProperties.put(MAP_FILE_BINARY_TO_BYTE_ARRAY, mapFileBinaryToByteArray); + if (mapFileBinaryToByteArray) { + typeMapping.put("file", "kotlin.ByteArray"); + typeMapping.put("binary", "kotlin.ByteArray"); + } + if (additionalProperties.containsKey(GENERATE_ONEOF_ANYOF_WRAPPERS)) { setGenerateOneOfAnyOfWrappers(Boolean.parseBoolean(additionalProperties.get(GENERATE_ONEOF_ANYOF_WRAPPERS).toString())); } diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache index 606b70f1fa8a..c5f5cb8a6f9e 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache @@ -87,6 +87,21 @@ import com.squareup.moshi.adapter val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -100,6 +115,7 @@ import com.squareup.moshi.adapter protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/others/kotlin-jvm-okhttp-parameter-tests/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/others/kotlin-jvm-okhttp-parameter-tests/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 2c84a6bf23ac..db1cc9cd8094 100644 --- a/samples/client/others/kotlin-jvm-okhttp-parameter-tests/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/others/kotlin-jvm-okhttp-parameter-tests/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -58,6 +58,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -71,6 +86,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-allOff-discriminator/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-allOff-discriminator/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 2c84a6bf23ac..db1cc9cd8094 100644 --- a/samples/client/petstore/kotlin-allOff-discriminator/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-allOff-discriminator/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -58,6 +58,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -71,6 +86,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-array-simple-string-jvm-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-array-simple-string-jvm-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 2c84a6bf23ac..db1cc9cd8094 100644 --- a/samples/client/petstore/kotlin-array-simple-string-jvm-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-array-simple-string-jvm-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -58,6 +58,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -71,6 +86,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-bigdecimal-default-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-bigdecimal-default-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 2c84a6bf23ac..db1cc9cd8094 100644 --- a/samples/client/petstore/kotlin-bigdecimal-default-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-bigdecimal-default-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -58,6 +58,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -71,6 +86,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-default-values-jvm-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-default-values-jvm-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 2c84a6bf23ac..db1cc9cd8094 100644 --- a/samples/client/petstore/kotlin-default-values-jvm-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-default-values-jvm-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -58,6 +58,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -71,6 +86,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-enum-default-value/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-enum-default-value/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 2c84a6bf23ac..db1cc9cd8094 100644 --- a/samples/client/petstore/kotlin-enum-default-value/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-enum-default-value/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -58,6 +58,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -71,6 +86,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 18243f43238e..311a85dcca71 100644 --- a/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -58,6 +58,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -71,6 +86,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 1d0b545aa6b2..9f531aafdd75 100644 --- a/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -58,6 +58,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -71,6 +86,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-json-request-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-json-request-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index fcc902c1d558..677e990930b7 100644 --- a/samples/client/petstore/kotlin-json-request-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-json-request-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -60,6 +60,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -73,6 +88,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-jvm-okhttp4-coroutines/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-jvm-okhttp4-coroutines/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index c419e4b0de2d..d2bd301a4786 100644 --- a/samples/client/petstore/kotlin-jvm-okhttp4-coroutines/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-jvm-okhttp4-coroutines/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -61,6 +61,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -74,6 +89,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 74b362833cc9..61653cbccef6 100644 --- a/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -58,6 +58,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -71,6 +86,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-modelMutable/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-modelMutable/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 74b362833cc9..61653cbccef6 100644 --- a/samples/client/petstore/kotlin-modelMutable/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-modelMutable/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -58,6 +58,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -71,6 +86,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-moshi-codegen/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-moshi-codegen/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 74b362833cc9..61653cbccef6 100644 --- a/samples/client/petstore/kotlin-moshi-codegen/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-moshi-codegen/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -58,6 +58,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -71,6 +86,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-name-parameter-mappings/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-name-parameter-mappings/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 2c84a6bf23ac..db1cc9cd8094 100644 --- a/samples/client/petstore/kotlin-name-parameter-mappings/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-name-parameter-mappings/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -58,6 +58,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -71,6 +86,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-nonpublic/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-nonpublic/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 96cab6d6d5d5..d4a4ef06d8b5 100644 --- a/samples/client/petstore/kotlin-nonpublic/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-nonpublic/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -58,6 +58,21 @@ internal open class ApiClient(val baseUrl: String, val client: Call.Factory = de val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -71,6 +86,7 @@ internal open class ApiClient(val baseUrl: String, val client: Call.Factory = de protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-nullable/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-nullable/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 74b362833cc9..61653cbccef6 100644 --- a/samples/client/petstore/kotlin-nullable/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-nullable/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -58,6 +58,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -71,6 +86,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-string/docs/PetApi.md b/samples/client/petstore/kotlin-string/docs/PetApi.md index 81f97cef914a..ea42a0d82f60 100644 --- a/samples/client/petstore/kotlin-string/docs/PetApi.md +++ b/samples/client/petstore/kotlin-string/docs/PetApi.md @@ -360,7 +360,7 @@ uploads an image val apiInstance = PetApi() val petId : kotlin.Long = 789 // kotlin.Long | ID of pet to update val additionalMetadata : kotlin.String = additionalMetadata_example // kotlin.String | Additional data to pass to server -val file : java.io.File = BINARY_DATA_HERE // java.io.File | file to upload +val file : kotlin.ByteArray = BINARY_DATA_HERE // kotlin.ByteArray | file to upload try { val result : ModelApiResponse = apiInstance.uploadFile(petId, additionalMetadata, file) println(result) @@ -378,7 +378,7 @@ try { | **additionalMetadata** | **kotlin.String**| Additional data to pass to server | [optional] | | Name | Type | Description | Notes | | ------------- | ------------- | ------------- | ------------- | -| **file** | **java.io.File**| file to upload | [optional] | +| **file** | **kotlin.ByteArray**| file to upload | [optional] | ### Return type diff --git a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/PetApi.kt index f159a87e1a63..0d5631a903de 100644 --- a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/PetApi.kt +++ b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/PetApi.kt @@ -589,7 +589,7 @@ class PetApi(basePath: kotlin.String = defaultBasePath, client: Call.Factory = A */ @Suppress("UNCHECKED_CAST") @Throws(IllegalStateException::class, IOException::class, UnsupportedOperationException::class, ClientException::class, ServerException::class) - fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String? = null, file: java.io.File? = null) : ModelApiResponse { + fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String? = null, file: kotlin.ByteArray? = null) : ModelApiResponse { val localVarResponse = uploadFileWithHttpInfo(petId = petId, additionalMetadata = additionalMetadata, file = file) return when (localVarResponse.responseType) { @@ -619,7 +619,7 @@ class PetApi(basePath: kotlin.String = defaultBasePath, client: Call.Factory = A */ @Suppress("UNCHECKED_CAST") @Throws(IllegalStateException::class, IOException::class) - fun uploadFileWithHttpInfo(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: java.io.File?) : ApiResponse { + fun uploadFileWithHttpInfo(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: kotlin.ByteArray?) : ApiResponse { val localVariableConfig = uploadFileRequestConfig(petId = petId, additionalMetadata = additionalMetadata, file = file) return request>, ModelApiResponse>( @@ -635,7 +635,7 @@ class PetApi(basePath: kotlin.String = defaultBasePath, client: Call.Factory = A * @param file file to upload (optional) * @return RequestConfig */ - fun uploadFileRequestConfig(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: java.io.File?) : RequestConfig>> { + fun uploadFileRequestConfig(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: kotlin.ByteArray?) : RequestConfig>> { val localVariableBody = mapOf( "additionalMetadata" to PartConfig(body = additionalMetadata, headers = mutableMapOf()), "file" to PartConfig(body = file, headers = mutableMapOf()),) diff --git a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 74b362833cc9..61653cbccef6 100644 --- a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -58,6 +58,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -71,6 +86,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index fe3124d35eb0..32236fe6bad0 100644 --- a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -58,6 +58,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -71,6 +86,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin-uppercase-enum/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-uppercase-enum/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 934673c9da9f..8dc4e33f54e4 100644 --- a/samples/client/petstore/kotlin-uppercase-enum/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-uppercase-enum/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -59,6 +59,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -72,6 +87,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() diff --git a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 74b362833cc9..61653cbccef6 100644 --- a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -58,6 +58,21 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie val builder: OkHttpClient.Builder = OkHttpClient.Builder() } + /** + * Guess Content-Type header from the given byteArray (defaults to "application/octet-stream"). + * + * @param byteArray The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String { + val contentType = try { + URLConnection.guessContentTypeFromStream(byteArray.inputStream()) + } catch (io: IOException) { + "application/octet-stream" + } + return contentType + } + /** * Guess Content-Type header from the given file (defaults to "application/octet-stream"). * @@ -71,6 +86,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie protected inline fun requestBody(content: T, mediaType: String?): RequestBody = when { + content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull()) content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) mediaType == FormDataMediaType -> MultipartBody.Builder() From 401d13ee2fbfa8afb11df10f12fe1914fa13dff9 Mon Sep 17 00:00:00 2001 From: Bruno Coelho <4brunu@gmail.com> Date: Fri, 11 Oct 2024 08:22:14 +0100 Subject: [PATCH 2/2] [kotlin] Map file and binary to ByteArray --- docs/generators/kotlin.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/generators/kotlin.md b/docs/generators/kotlin.md index 05f6c4cbab04..82011d0e54b6 100644 --- a/docs/generators/kotlin.md +++ b/docs/generators/kotlin.md @@ -31,6 +31,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools| |idea|Add IntellJ Idea plugin and mark Kotlin main and test folders as source folders.| |false| |library|Library template (sub-template) to use|
**jvm-ktor**
Platform: Java Virtual Machine. HTTP client: Ktor 1.6.7. JSON processing: Gson, Jackson (default).
**jvm-okhttp4**
[DEFAULT] Platform: Java Virtual Machine. HTTP client: OkHttp 4.2.0 (Android 5.0+ and Java 8+). JSON processing: Moshi 1.8.0.
**jvm-spring-webclient**
Platform: Java Virtual Machine. HTTP: Spring 5 (or 6 with useSpringBoot3 enabled) WebClient. JSON processing: Jackson.
**jvm-spring-restclient**
Platform: Java Virtual Machine. HTTP: Spring 6 RestClient. JSON processing: Jackson.
**jvm-retrofit2**
Platform: Java Virtual Machine. HTTP client: Retrofit 2.6.2.
**multiplatform**
Platform: Kotlin multiplatform. HTTP client: Ktor 1.6.7. JSON processing: Kotlinx Serialization: 1.2.1.
**jvm-volley**
Platform: JVM for Android. HTTP client: Volley 1.2.1. JSON processing: gson 2.8.9
**jvm-vertx**
Platform: Java Virtual Machine. HTTP client: Vert.x Web Client. JSON processing: Moshi, Gson or Jackson.
|jvm-okhttp4| +|mapFileBinaryToByteArray|Map File and Binary to ByteArray (default: false)| |false| |modelMutable|Create mutable models| |false| |moshiCodeGen|Whether to enable codegen with the Moshi library. Refer to the [official Moshi doc](https://github.com/square/moshi#codegen) for more info.| |false| |nullableReturnType|Nullable return type| |false|