如何用Moshi从JSON构建Kotlin API类?API通信重构需求
嘿,我明白你想要的是让你的API类既能通过直接传属性快速实例化,又能轻松从JSON字符串构建,同时还能方便地序列化成JSON——用Moshi完全可以搞定,而且实现起来很简洁!我给你梳理一套可行的方案:
第一步:配置Moshi依赖
首先得在你的项目里引入Moshi的核心库和Kotlin代码生成插件,这样它能自动为你的类生成高效的JSON适配器。以Gradle为例,在build.gradle.kts里添加:
dependencies { implementation("com.squareup.moshi:moshi:1.15.0") kapt("com.squareup.moshi:moshi-kotlin-codegen:1.15.0") }
第二步:定义你的API类并添加Moshi支持
用Kotlin数据类来定义你的API模型,直接保留你想要的“传属性实例化”的能力,同时加上@JsonClass(generateAdapter = true)注解,让Moshi自动生成适配逻辑:
import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) data class User( val email: String, // 如果JSON字段名和Kotlin属性名不一致,用@Json映射 @Json(name = "other_property") val otherProperty: String )
第三步:实现JSON实例化逻辑
你想要两种方式:User.fromJson(jsonString)(当前的理想替代)和更简洁的User(jsonString)。我们可以通过伴生对象和构造函数重载来实现:
import com.squareup.moshi.Moshi import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory @JsonClass(generateAdapter = true) data class User( val email: String, @Json(name = "other_property") val otherProperty: String ) { companion object { // 初始化Moshi实例,添加Kotlin适配工厂处理空安全等特性 private val moshi = Moshi.Builder() .add(KotlinJsonAdapterFactory()) .build() private val userAdapter = moshi.adapter(User::class.java) // 工厂方法:推荐使用,语义清晰且不重复解析JSON fun fromJson(jsonString: String): User? { return runCatching { userAdapter.fromJson(jsonString) }.getOrNull() } } // 重载构造函数:实现你想要的User(jsonString)形式 // 注意:如果主构造函数有String类型参数,会出现歧义,这种情况建议只用fromJson工厂方法 constructor(jsonString: String) : this( checkNotNull(fromJson(jsonString)?.email) { "Invalid JSON: missing email" }, checkNotNull(fromJson(jsonString)?.otherProperty) { "Invalid JSON: missing otherProperty" } ) }
第四步:实现序列化toJson()
直接在类里添加一个扩展方法,用Moshi适配器完成序列化:
// 接上面的User类 fun toJson(): String { return userAdapter.toJson(this) }
实际用法示例
// 1. 直接传属性实例化 val userFromParams = User("user@example.com", "othervalue") // 2. 从JSON字符串实例化(两种方式) val jsonString = """{"email":"user@example.com","other_property":"othervalue"}""" // 方式1:工厂方法(推荐,更安全) val userFromString1 = User.fromJson(jsonString) ?: error("Failed to parse User from JSON") // 方式2:重载构造函数 val userFromString2 = User(jsonString) // 3. 序列化为JSON字符串 val serializedJson = userFromParams.toJson()
一些注意事项
- 重载构造函数的方式会解析两次JSON(调用fromJson两次),如果追求性能,优先用
fromJson工厂方法。 - 实际项目中尽量避免用
!!,改用runCatching、?:等方式处理解析失败的情况,避免空指针崩溃。 - 如果你的类有自定义的序列化/反序列化逻辑,可以自己实现
JsonAdapter并注册到Moshi实例中。
内容的提问来源于stack exchange,提问作者Martin Westin
相关产品推荐
相关产品推荐

