如何在Ktor中反序列化含不同类型列表的JSON响应?
解决方案
1. 重构数据类:使用泛型Result类
将重复的ResultOne和ResultTwo替换为单一泛型Result类,通过类型占位符兼容不同的列表元素类型:
@Serializable data class Result<T>( val count: Int, val result: List<T> ) @Serializable data class TypeOne( val str1: String, val str2: String, val int1: Int ) @Serializable data class TypeTwo( val str1: String, val dbl1: Double, val int1: Int )
2. 复用HTTP请求方法:泛型+Reified类型
借助Kotlin的reified泛型特性,让Ktor在运行时获取具体序列化类型,实现请求方法的完全复用:
// 保留原HttpClient配置 private val httpClient = HttpClient { install(ContentNegotiation) { json(Json{ isLenient = true ignoreUnknownKeys = true }) } } // 泛型请求方法,reified关键字让编译器保留类型信息 private suspend inline fun <reified T> fetchResults(ints: List<Int>): Result<T> { return httpClient.get("https://my.api.com/search") { // 可在这里统一处理查询参数,比如传入的ints列表 url { parameters.appendAll("ids", ints.map { it.toString() }) } }.body() } // 调用示例 fun getResultTypeOne() { val response = runBlocking { fetchResults<TypeOne>(listOf(1,2)).result } } fun getResultTypeTwo() { val response = runBlocking { fetchResults<TypeTwo>(listOf(1,2)).result } }
核心说明
- 泛型Result类:通过
<T>抽象列表元素类型,彻底消除结构重复的Result类定义。 - Reified泛型:
inline fun <reified T>让Kotlin编译器在编译期保留T的具体类型,确保Ktor能正确调用Kotlinx Serialization的序列化器,完成JSON到目标类型的解析。 - 扩展灵活性:如果不同类型请求需要差异化参数,可在
fetchResults中添加参数判断逻辑,或直接传入参数配置块,进一步提升复用性。
内容的提问来源于stack exchange,提问作者user4414119
相关产品推荐
相关产品推荐

