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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:15:35