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

如何创建返回Map的自定义Moshi JsonAdapter并适配Retrofit

实现Moshi适配器将API返回的JSON转为Map<String, String>并配合Retrofit使用

完全可以实现你的需求,以下是修正后的完整方案:

一、修正自定义Moshi适配器

你的适配器目标是处理Map<String, String>类型,无需绑定到多余的Countries类。如果不需要将Map序列化为JSON,可以直接删除无用的@ToJson方法;若后续需要序列化,可保留并修正实现:

class CountriesAdapter {

    @FromJson
    fun fromJson(reader: JsonReader): Map<String, String> {
        val countries = mutableMapOf<String, String>()
        with(reader) {
            beginObject()
            while (hasNext()) {
                countries[nextName()] = nextString()
            }
            endObject()
        }
        return countries
    }

    // 可选:如果需要将Map序列化为JSON,保留此方法;否则可删除
    @ToJson
    fun toJson(writer: JsonWriter, map: Map<String, String>) {
        with(writer) {
            beginObject()
            map.forEach { (key, value) ->
                name(key)
                value(value)
            }
            endObject()
        }
    }
}

二、修正Retrofit API接口定义

API接口方法应直接返回Call<Map<String, String>>,而非Call<Countries>,让Retrofit明确要解析的目标类型:

interface APIInterface {
    @GET("path/to/your/countries/api") // 替换为实际的API路径
    fun getCountries(): Call<Map<String, String>>
}

三、修正Retrofit初始化与调用

移除无用的Countries数据类,Retrofit会通过Moshi自动将JSON解析为Map,无需手动调用适配器方法:

val moshi = Moshi.Builder()
    .add(CountriesAdapter())
    .addLast(KotlinJsonAdapterFactory())
    .build()

val retrofit = Retrofit.Builder()
    .baseUrl("https://flagcdn.com")
    .addConverterFactory(MoshiConverterFactory.create(moshi))
    .build()
    .create(APIInterface::class.java)

retrofit.getCountries().enqueue(object : Callback<Map<String, String>> {
    override fun onResponse(call: Call<Map<String, String>>, response: Response<Map<String, String>>) {
        if (response.isSuccessful) {
            // 直接获取解析后的Map
            val countriesMap = response.body()
            countriesMap?.let {
                // 这里处理Map数据,比如赋值给LiveData
                _countries.value = it
            }
        }
    }

    override fun onFailure(call: Call<Map<String, String>>, t: Throwable) {
        // 处理请求失败逻辑
    }
})

关键说明

  • Moshi会自动匹配@FromJson方法处理Map<String, String>类型的解析,无需手动调用适配器的fromJson方法。
  • 移除Countries数据类是因为我们不需要将JSON映射到固定实体类,直接转为键值对Map即可满足需求。
  • 当前实现适配你提供的API格式(所有值均为String类型),若后续API返回非String值,需在适配器中添加类型判断逻辑。

内容的提问来源于stack exchange,提问作者Daniel Bertoldi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 06:42:36