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

如何获取GitHub用户所有仓库并使用Moshi解析无键JSON数组

用Moshi解析无键JSON数组到Kotlin数据类(GitHub仓库列表场景)

我明白你遇到的问题了——GitHub API返回的仓库列表是一个没有外层键的纯JSON数组,平时用Moshi大多处理带外层键的对象,这种数组确实需要稍微调整下解析逻辑,其实解决起来很简单,我给你一步步拆解代码示例:

第一步:定义GitHub仓库对应的数据类

先根据API返回的JSON结构,创建匹配的数据类,把你需要的字段都加上,字段名如果和JSON里的不一致,可以用@Json注解映射:

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass

@JsonClass(generateAdapter = true)
data class GitHubRepo(
    val id: Long,
    val node_id: String,
    // 示例:映射JSON里的name字段到Kotlin的repoName属性
    @Json(name = "name") val repoName: String,
    // 仓库描述可能为空,所以用可空类型
    @Json(name = "description") val repoDescription: String?,
    // 可以继续添加你需要的其他字段,比如star数量、仓库地址等
    val stargazers_count: Int,
    val html_url: String
)

@JsonClass(generateAdapter = true)是让Moshi自动生成解析适配器,避免手动写适配器的麻烦。

第二步:核心解析逻辑(处理无键数组)

因为返回的是数组,我们需要明确告诉Moshi要解析成List<GitHubRepo>类型,这里有两种常用实现方式:

方式一:用Moshi的Types类创建类型令牌(兼容所有Kotlin版本)

由于泛型擦除的问题,Moshi需要明确的类型信息才能正确解析,我们可以用Types.newParameterizedType来创建列表的类型令牌:

import com.squareup.moshi.Moshi
import com.squareup.moshi.Types

fun parseGitHubRepos(jsonString: String): List<GitHubRepo> {
    // 初始化Moshi实例
    val moshi = Moshi.Builder().build()
    // 创建List<GitHubRepo>的类型令牌
    val repoListType = Types.newParameterizedType(List::class.java, GitHubRepo::class.java)
    // 获取对应的解析适配器
    val adapter = moshi.adapter<List<GitHubRepo>>(repoListType)
    
    // 解析JSON字符串,为空的话返回空列表避免空指针
    return adapter.fromJson(jsonString) ?: emptyList()
}

方式二:用Kotlin的typeOf(Kotlin 1.9+版本可用,更简洁)

如果你用的是较新的Kotlin版本,可以用typeOf简化类型令牌的创建:

import com.squareup.moshi.Moshi
import kotlin.reflect.typeOf

fun parseGitHubRepos(jsonString: String): List<GitHubRepo> {
    val moshi = Moshi.Builder().build()
    val adapter = moshi.adapter<List<GitHubRepo>>(typeOf<List<GitHubRepo>>())
    
    return adapter.fromJson(jsonString) ?: emptyList()
}

额外优化:配合Retrofit请求API

如果你是用Retrofit来调用GitHub API,那更省心——直接在接口方法里返回List<GitHubRepo>即可,Retrofit会自动和Moshi协同处理数组解析,不需要手动处理类型令牌:

import retrofit2.http.GET
import retrofit2.http.Path

interface GitHubApiService {
    // 请求指定用户的仓库列表
    @GET("users/{username}/repos")
    suspend fun getUserRepos(@Path("username") username: String): List<GitHubRepo>
}

这样发起请求后,Retrofit会自动把API返回的无键JSON数组转换成List<GitHubRepo>对象列表,直接用就行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 01:02:37