You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Ktor+Mustache模板报错:MustacheContent无序列化器求解决方案

解决Ktor中MustacheContent序列化异常的方案

你遇到的kotlinx.serialization.SerializationException是因为Ktor的ContentNegotiation插件尝试序列化MustacheContent,但该类未标记@Serializable。以下是几种可行的解决办法:

方案1:返回时指定ContentType

在路由中返回MustacheContent时,明确指定ContentType.Text.Html,让Ktor将请求交给Mustache插件处理,而非ContentNegotiation:

get("/") {
    val model = mapOf("title" to "Hello Ktor")
    call.respond(
        MustacheContent("template.hbs", model),
        ContentType.Text.Html
    )
}

方案2:调整ContentNegotiation配置

修改ContentNegotiation的安装代码,仅对JSON等需要序列化的类型生效,忽略HTML类型:

install(ContentNegotiation) {
    json()
    defaultContentType(ContentType.Application.Json)
}

或者为HTML类型注册一个空转换器,让Mustache插件接管处理:

install(ContentNegotiation) {
    json()
    register(ContentType.Text.Html) {
        object : ContentConverter {
            override suspend fun serialize(
                contentType: ContentType,
                value: Any,
                charset: Charset
            ): OutgoingContent? = null

            override suspend fun deserialize(charset: Charset, typeInfo: TypeInfo, content: ByteReadChannel): Any? = null
        }
    }
}

方案3:自定义序列化器并注册

如果必须让ContentNegotiation处理MustacheContent,可以自定义序列化器并全局注册:

import io.ktor.server.mustache.MustacheContent
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.encoding.Decoder

@Serializer(forClass = MustacheContent::class)
object MustacheContentSerializer : KSerializer<MustacheContent> {
    override val descriptor: SerialDescriptor =
        PrimitiveSerialDescriptor("MustacheContent", PrimitiveKind.STRING)

    override fun serialize(encoder: Encoder, value: MustacheContent) {
        encoder.encodeString("Template: ${value.template}, Model: ${value.model}")
    }

    override fun deserialize(decoder: Decoder): MustacheContent {
        throw UnsupportedOperationException("Deserializing MustacheContent is not supported")
    }
}

// 在应用模块中注册
fun Application.module() {
    SerializersModule {
        contextual(MustacheContent::class, MustacheContentSerializer)
    }
    // 其他插件安装逻辑...
}

通常方案1和方案2更符合Mustache的设计初衷,因为MustacheContent本就应由Mustache插件负责渲染为HTML响应,无需ContentNegotiation序列化。

内容的提问来源于stack exchange,提问作者Guelque Hadrien

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 21:15:42