This feature provides automatic content conversion according to Content-Type and Accept headers.
io.ktor.features.ContentNegotiation 类中定义,无需任何额外构件。
The ContentNegotiation feature allows you to register and configure custom converters.
install(ContentNegotiation) {
register(MyContentType, MyContentTypeConverter()) {
// Optionally configure the converter...
}
}
For example:
install(ContentNegotiation) {
register(ContentType.Application.Json, JacksonConverter())
}
When you respond with an object that is not directly handled, like a custom data class,
this feature checks the client’s Accept header to determine which Content-Type will be
used and thus which ContentConverter will be called.
call.respond(MyDataClass("hello", "world"))
Right now, the only supported ContentNegotiation strategy when sending, is the
client’s Accept header. There is an issue to implement other strategies.
When receiving, the Content-Type of the request will be used to determine
which ContentConverter will be used to process that request:
val myDataClass = call.receive<MyDataClass>()
If you want to write your own converter, you have to implement the ContentConverter interface:
interface ContentConverter {
suspend fun convertForSend(context: PipelineContext<Any, ApplicationCall>, contentType: ContentType, value: Any): Any?
suspend fun convertForReceive(context: PipelineContext<ApplicationReceiveRequest, ApplicationCall>): Any?
}
For example, the GsonConverter implementation looks like:
class GsonConverter(private val gson: Gson = Gson()) : ContentConverter {
override suspend fun convertForSend(context: PipelineContext<Any, ApplicationCall>, contentType: ContentType, value: Any): Any? {
return TextContent(gson.toJson(value), contentType.withCharset(context.call.suitableCharset()))
}
override suspend fun convertForReceive(context: PipelineContext<ApplicationReceiveRequest, ApplicationCall>): Any? {
val request = context.subject
val channel = request.value as? ByteReadChannel ?: return null
val reader = channel.readRemaining().readText((context.call.request.contentCharset() ?: Charsets.UTF_8).newDecoder()).reader()
return gson.fromJson(reader, request.type.javaObjectType)
}
}
Ktor provide some content converters out of the box:
application/json