Content conversion based on Content-Type and Accept headers

预计阅读时间:2分钟

此功能根据Content-TypeAccept标头提供自动的内容转换.

此功能在io.ktor.features.ContentNegotiation类中io.ktor.features.ContentNegotiation ,不需要其他工件.

Basic Usage

ContentNegotiation功能使您可以注册和配置自定义转换器.

install(ContentNegotiation) {
    register(MyContentType, MyContentTypeConverter()) {
        // Optionally configure the converter...
    }
}

例如:

install(ContentNegotiation) {
    register(ContentType.Application.Json, JacksonConverter())
}

Sending

当您对未直接处理的对象(例如自定义数据类)进行响应时,此功能将检查客户端的Accept标头,以确定将使用哪个Content-Type ,从而调用哪个ContentConverter .

call.respond(MyDataClass("hello", "world"))

目前,发送时唯一受支持的ContentNegotiation策略是客户端的Accept标头. 实施其他策略存在一个问题 .

Receiving

接收时,请求的Content-Type将用于确定将使用哪个ContentConverter来处理该请求:

val myDataClass = call.receive<MyDataClass>()

The ContentConverter interface

如果要编写自己的转换器,则必须实现ContentConverter接口:

interface ContentConverter {
    suspend fun convertForSend(context: PipelineContext<Any, ApplicationCall>, contentType: ContentType, value: Any): Any?
    suspend fun convertForReceive(context: PipelineContext<ApplicationReceiveRequest, ApplicationCall>): Any?
}

例如, GsonConverter实现看起来像:

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)
    }
}

Available out of the box ContentConverter

Ktor提供一些现成的内容转换器:

by  ICOPY.SITE