Skip to content

Commit 05d4aa9

Browse files
authored
[kotlin][client] support text/plain in okhttp (#20250)
* refactor: simplify application/octet-stream check * feat: support text/plain in kotlin okhttp client * refactor: remove redundant always-false condition content is ByteArray is checked earlier
1 parent 8a07557 commit 05d4aa9

File tree

23 files changed

+135
-89
lines changed
  • modules/openapi-generator/src/main
  • samples/client
    • others/kotlin-jvm-okhttp-parameter-tests/src/main/kotlin/org/openapitools/client/infrastructure
    • petstore
      • kotlin/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-allOff-discriminator/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-array-simple-string-jvm-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-bigdecimal-default-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-default-values-jvm-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-enum-default-value/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-explicit/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-jackson/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-json-request-string/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-jvm-okhttp4-coroutines/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-modelMutable/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-moshi-codegen/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-name-parameter-mappings/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-nonpublic/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-nullable/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure
      • kotlin-uppercase-enum/src/main/kotlin/org/openapitools/client/infrastructure

23 files changed

+135
-89
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,9 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
962962
).trim();
963963
return "multipart/form-data".equals(mediaType)
964964
|| "application/x-www-form-urlencoded".equals(mediaType)
965-
|| (mediaType.startsWith("application/") && (mediaType.endsWith("json") || mediaType.endsWith("octet-stream")));
965+
|| (mediaType.startsWith("application/") && mediaType.endsWith("json"))
966+
|| "application/octet-stream".equals(mediaType)
967+
|| "text/plain".equals(mediaType);
966968
};
967969
operation.consumes = operation.consumes == null ? null : operation.consumes.stream()
968970
.filter(isSerializable)

modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ import com.squareup.moshi.adapter
7070
protected const val FormUrlEncMediaType: String = "application/x-www-form-urlencoded"
7171
protected const val XmlMediaType: String = "application/xml"
7272
protected const val OctetMediaType: String = "application/octet-stream"
73+
protected const val TextMediaType: String = "text/plain"
7374
7475
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val apiKey: MutableMap<String, String> = mutableMapOf()
7576
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val apiKeyPrefix: MutableMap<String, String> = mutableMapOf()
@@ -209,10 +210,10 @@ import com.squareup.moshi.adapter
209210
.toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull())
210211
}
211212
mediaType == XmlMediaType -> throw UnsupportedOperationException("xml not currently supported.")
212-
mediaType == OctetMediaType && content is ByteArray ->
213-
content.toRequestBody(OctetMediaType.toMediaTypeOrNull())
213+
mediaType == TextMediaType && content is String ->
214+
content.toRequestBody(TextMediaType.toMediaTypeOrNull())
214215
// TODO: this should be extended with other serializers
215-
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, byte body and File body.")
216+
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, text body, byte body and File body.")
216217
}
217218

218219
{{#moshi}}
@@ -298,7 +299,8 @@ import com.squareup.moshi.adapter
298299
}}{{#kotlinx_serialization}}Serializer.kotlinxSerializationJson.decodeFromString<T>(bodyContent){{/kotlinx_serialization}}
299300
}
300301
mediaType == OctetMediaType -> body.bytes() as? T
301-
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.")
302+
mediaType == TextMediaType -> body.string() as? T
303+
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body, text body and byte body.")
302304
}
303305
}
304306

samples/client/others/kotlin-jvm-okhttp-parameter-tests/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
4141
protected const val FormUrlEncMediaType: String = "application/x-www-form-urlencoded"
4242
protected const val XmlMediaType: String = "application/xml"
4343
protected const val OctetMediaType: String = "application/octet-stream"
44+
protected const val TextMediaType: String = "text/plain"
4445

4546
val apiKey: MutableMap<String, String> = mutableMapOf()
4647
val apiKeyPrefix: MutableMap<String, String> = mutableMapOf()
@@ -169,10 +170,10 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
169170
.toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull())
170171
}
171172
mediaType == XmlMediaType -> throw UnsupportedOperationException("xml not currently supported.")
172-
mediaType == OctetMediaType && content is ByteArray ->
173-
content.toRequestBody(OctetMediaType.toMediaTypeOrNull())
173+
mediaType == TextMediaType && content is String ->
174+
content.toRequestBody(TextMediaType.toMediaTypeOrNull())
174175
// TODO: this should be extended with other serializers
175-
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, byte body and File body.")
176+
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, text body, byte body and File body.")
176177
}
177178

178179
@OptIn(ExperimentalStdlibApi::class)
@@ -243,7 +244,8 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
243244
Serializer.moshi.adapter<T>().fromJson(bodyContent)
244245
}
245246
mediaType == OctetMediaType -> body.bytes() as? T
246-
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.")
247+
mediaType == TextMediaType -> body.string() as? T
248+
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body, text body and byte body.")
247249
}
248250
}
249251

samples/client/petstore/kotlin-allOff-discriminator/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
4141
protected const val FormUrlEncMediaType: String = "application/x-www-form-urlencoded"
4242
protected const val XmlMediaType: String = "application/xml"
4343
protected const val OctetMediaType: String = "application/octet-stream"
44+
protected const val TextMediaType: String = "text/plain"
4445

4546
val apiKey: MutableMap<String, String> = mutableMapOf()
4647
val apiKeyPrefix: MutableMap<String, String> = mutableMapOf()
@@ -169,10 +170,10 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
169170
.toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull())
170171
}
171172
mediaType == XmlMediaType -> throw UnsupportedOperationException("xml not currently supported.")
172-
mediaType == OctetMediaType && content is ByteArray ->
173-
content.toRequestBody(OctetMediaType.toMediaTypeOrNull())
173+
mediaType == TextMediaType && content is String ->
174+
content.toRequestBody(TextMediaType.toMediaTypeOrNull())
174175
// TODO: this should be extended with other serializers
175-
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, byte body and File body.")
176+
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, text body, byte body and File body.")
176177
}
177178

178179
@OptIn(ExperimentalStdlibApi::class)
@@ -243,7 +244,8 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
243244
Serializer.moshi.adapter<T>().fromJson(bodyContent)
244245
}
245246
mediaType == OctetMediaType -> body.bytes() as? T
246-
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.")
247+
mediaType == TextMediaType -> body.string() as? T
248+
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body, text body and byte body.")
247249
}
248250
}
249251

samples/client/petstore/kotlin-array-simple-string-jvm-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
4141
protected const val FormUrlEncMediaType: String = "application/x-www-form-urlencoded"
4242
protected const val XmlMediaType: String = "application/xml"
4343
protected const val OctetMediaType: String = "application/octet-stream"
44+
protected const val TextMediaType: String = "text/plain"
4445

4546
val apiKey: MutableMap<String, String> = mutableMapOf()
4647
val apiKeyPrefix: MutableMap<String, String> = mutableMapOf()
@@ -169,10 +170,10 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
169170
.toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull())
170171
}
171172
mediaType == XmlMediaType -> throw UnsupportedOperationException("xml not currently supported.")
172-
mediaType == OctetMediaType && content is ByteArray ->
173-
content.toRequestBody(OctetMediaType.toMediaTypeOrNull())
173+
mediaType == TextMediaType && content is String ->
174+
content.toRequestBody(TextMediaType.toMediaTypeOrNull())
174175
// TODO: this should be extended with other serializers
175-
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, byte body and File body.")
176+
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, text body, byte body and File body.")
176177
}
177178

178179
@OptIn(ExperimentalStdlibApi::class)
@@ -243,7 +244,8 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
243244
Serializer.moshi.adapter<T>().fromJson(bodyContent)
244245
}
245246
mediaType == OctetMediaType -> body.bytes() as? T
246-
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.")
247+
mediaType == TextMediaType -> body.string() as? T
248+
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body, text body and byte body.")
247249
}
248250
}
249251

samples/client/petstore/kotlin-bigdecimal-default-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
4141
protected const val FormUrlEncMediaType: String = "application/x-www-form-urlencoded"
4242
protected const val XmlMediaType: String = "application/xml"
4343
protected const val OctetMediaType: String = "application/octet-stream"
44+
protected const val TextMediaType: String = "text/plain"
4445

4546
val apiKey: MutableMap<String, String> = mutableMapOf()
4647
val apiKeyPrefix: MutableMap<String, String> = mutableMapOf()
@@ -169,10 +170,10 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
169170
.toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull())
170171
}
171172
mediaType == XmlMediaType -> throw UnsupportedOperationException("xml not currently supported.")
172-
mediaType == OctetMediaType && content is ByteArray ->
173-
content.toRequestBody(OctetMediaType.toMediaTypeOrNull())
173+
mediaType == TextMediaType && content is String ->
174+
content.toRequestBody(TextMediaType.toMediaTypeOrNull())
174175
// TODO: this should be extended with other serializers
175-
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, byte body and File body.")
176+
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, text body, byte body and File body.")
176177
}
177178

178179
@OptIn(ExperimentalStdlibApi::class)
@@ -243,7 +244,8 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
243244
Serializer.moshi.adapter<T>().fromJson(bodyContent)
244245
}
245246
mediaType == OctetMediaType -> body.bytes() as? T
246-
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.")
247+
mediaType == TextMediaType -> body.string() as? T
248+
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body, text body and byte body.")
247249
}
248250
}
249251

samples/client/petstore/kotlin-default-values-jvm-okhttp4/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
4141
protected const val FormUrlEncMediaType: String = "application/x-www-form-urlencoded"
4242
protected const val XmlMediaType: String = "application/xml"
4343
protected const val OctetMediaType: String = "application/octet-stream"
44+
protected const val TextMediaType: String = "text/plain"
4445

4546
val apiKey: MutableMap<String, String> = mutableMapOf()
4647
val apiKeyPrefix: MutableMap<String, String> = mutableMapOf()
@@ -169,10 +170,10 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
169170
.toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull())
170171
}
171172
mediaType == XmlMediaType -> throw UnsupportedOperationException("xml not currently supported.")
172-
mediaType == OctetMediaType && content is ByteArray ->
173-
content.toRequestBody(OctetMediaType.toMediaTypeOrNull())
173+
mediaType == TextMediaType && content is String ->
174+
content.toRequestBody(TextMediaType.toMediaTypeOrNull())
174175
// TODO: this should be extended with other serializers
175-
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, byte body and File body.")
176+
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, text body, byte body and File body.")
176177
}
177178

178179
@OptIn(ExperimentalStdlibApi::class)
@@ -243,7 +244,8 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
243244
Serializer.moshi.adapter<T>().fromJson(bodyContent)
244245
}
245246
mediaType == OctetMediaType -> body.bytes() as? T
246-
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.")
247+
mediaType == TextMediaType -> body.string() as? T
248+
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body, text body and byte body.")
247249
}
248250
}
249251

samples/client/petstore/kotlin-enum-default-value/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
4141
protected const val FormUrlEncMediaType: String = "application/x-www-form-urlencoded"
4242
protected const val XmlMediaType: String = "application/xml"
4343
protected const val OctetMediaType: String = "application/octet-stream"
44+
protected const val TextMediaType: String = "text/plain"
4445

4546
val apiKey: MutableMap<String, String> = mutableMapOf()
4647
val apiKeyPrefix: MutableMap<String, String> = mutableMapOf()
@@ -169,10 +170,10 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
169170
.toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull())
170171
}
171172
mediaType == XmlMediaType -> throw UnsupportedOperationException("xml not currently supported.")
172-
mediaType == OctetMediaType && content is ByteArray ->
173-
content.toRequestBody(OctetMediaType.toMediaTypeOrNull())
173+
mediaType == TextMediaType && content is String ->
174+
content.toRequestBody(TextMediaType.toMediaTypeOrNull())
174175
// TODO: this should be extended with other serializers
175-
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, byte body and File body.")
176+
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, text body, byte body and File body.")
176177
}
177178

178179
@OptIn(ExperimentalStdlibApi::class)
@@ -243,7 +244,8 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
243244
Serializer.moshi.adapter<T>().fromJson(bodyContent)
244245
}
245246
mediaType == OctetMediaType -> body.bytes() as? T
246-
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.")
247+
mediaType == TextMediaType -> body.string() as? T
248+
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body, text body and byte body.")
247249
}
248250
}
249251

samples/client/petstore/kotlin-explicit/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public open class ApiClient(public val baseUrl: String, public val client: Call.
4141
protected const val FormUrlEncMediaType: String = "application/x-www-form-urlencoded"
4242
protected const val XmlMediaType: String = "application/xml"
4343
protected const val OctetMediaType: String = "application/octet-stream"
44+
protected const val TextMediaType: String = "text/plain"
4445

4546
public val apiKey: MutableMap<String, String> = mutableMapOf()
4647
public val apiKeyPrefix: MutableMap<String, String> = mutableMapOf()
@@ -169,10 +170,10 @@ public open class ApiClient(public val baseUrl: String, public val client: Call.
169170
.toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull())
170171
}
171172
mediaType == XmlMediaType -> throw UnsupportedOperationException("xml not currently supported.")
172-
mediaType == OctetMediaType && content is ByteArray ->
173-
content.toRequestBody(OctetMediaType.toMediaTypeOrNull())
173+
mediaType == TextMediaType && content is String ->
174+
content.toRequestBody(TextMediaType.toMediaTypeOrNull())
174175
// TODO: this should be extended with other serializers
175-
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, byte body and File body.")
176+
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, text body, byte body and File body.")
176177
}
177178

178179
@OptIn(ExperimentalStdlibApi::class)
@@ -243,7 +244,8 @@ public open class ApiClient(public val baseUrl: String, public val client: Call.
243244
Serializer.moshi.adapter<T>().fromJson(bodyContent)
244245
}
245246
mediaType == OctetMediaType -> body.bytes() as? T
246-
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.")
247+
mediaType == TextMediaType -> body.string() as? T
248+
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body, text body and byte body.")
247249
}
248250
}
249251

samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
4141
protected const val FormUrlEncMediaType: String = "application/x-www-form-urlencoded"
4242
protected const val XmlMediaType: String = "application/xml"
4343
protected const val OctetMediaType: String = "application/octet-stream"
44+
protected const val TextMediaType: String = "text/plain"
4445

4546
val apiKey: MutableMap<String, String> = mutableMapOf()
4647
val apiKeyPrefix: MutableMap<String, String> = mutableMapOf()
@@ -169,10 +170,10 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
169170
.toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull())
170171
}
171172
mediaType == XmlMediaType -> throw UnsupportedOperationException("xml not currently supported.")
172-
mediaType == OctetMediaType && content is ByteArray ->
173-
content.toRequestBody(OctetMediaType.toMediaTypeOrNull())
173+
mediaType == TextMediaType && content is String ->
174+
content.toRequestBody(TextMediaType.toMediaTypeOrNull())
174175
// TODO: this should be extended with other serializers
175-
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, byte body and File body.")
176+
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, text body, byte body and File body.")
176177
}
177178

178179
protected inline fun <reified T: Any?> responseBody(response: Response, mediaType: String? = JsonMediaType): T? {
@@ -242,7 +243,8 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
242243
Serializer.gson.fromJson(bodyContent, (object: TypeToken<T>(){}).getType())
243244
}
244245
mediaType == OctetMediaType -> body.bytes() as? T
245-
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.")
246+
mediaType == TextMediaType -> body.string() as? T
247+
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body, text body and byte body.")
246248
}
247249
}
248250

0 commit comments

Comments
 (0)