使用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
相关产品推荐
相关产品推荐

