【问题标题】:IllegalArgumentException Moshi thinks I'm using ArrayList(java) when I'm using List(Kotlin)IllegalArgumentException Moshi 认为我在使用 List(Kotlin) 时使用的是 ArrayList(java)
【发布时间】:2021-07-24 18:11:40
【问题描述】:

我是 Kotlin 的新手,但我仍然没有完全掌握某些东西的语法,尤其是在 lambda 中。我正在尝试为 uni 项目构建一个简单的 REST api,目前正在与 ktor、exposed 和 moshi 混淆。 但是我收到以下错误:

java.lang.IllegalArgumentException: No JsonAdapter for class java.util.ArrayList, you should probably use List instead of ArrayList (Moshi only supports the collection interfaces by default) or else register a custom JsonAdapter.

我不知道如何解决这个问题,因为我确实使用了一个列表,但是我的猜测是 Kotlin 列表被编译为 java 的 ArrayList。

根据我的谷歌搜索,这应该可以工作并且足够了,但我想情况并非如此:

    val listType = Types.newParameterizedType(List::class.java, Author::class.java)
    val moshi = Moshi.Builder().build()
    val adapter: JsonAdapter<List<Author>> = moshi.adapter(listType)

这里是完整的代码(除了数据库设置/连接):

fun Application.module(testing: Boolean = false) {
    install(CallLogging)
    val listType = Types.newParameterizedType(List::class.java, Author::class.java)
    val moshi = Moshi.Builder().build()
    val adapter: JsonAdapter<List<Author>> = moshi.adapter(listType)
    install(ContentNegotiation) {
        /*gson {
            setPrettyPrinting()
        }*/
        moshi(moshi)
    }

    routing {
        get("/authors") {
            val authorList = mutableListOf<Author>()
            transaction(db) {
                addLogger(StdOutSqlLogger)
                SchemaUtils.create(Authors)
                val query = "SELECT a.id, a.name, a.age, c.name as `country`\n" +
                        " FROM authors a, countries c\n" +
                        " WHERE a.country_id = c.id ORDER BY a.id";
                TransactionManager.current().exec(query) { rs ->
                    while (rs.next()) {
                        authorList += Author(
                            id = rs.getInt("id"), name = rs.getString("name"),
                            age = rs.getInt("age"), country = rs.getString("country")
                        )
                    }
                }
            }
            val result: List<Author> = authorList.toList()
            adapter.toJson(result)
            print("\n\n${result}\n\n")
            call.respond(HttpStatusCode.OK, result)
        }
    }
}  

我的数据类如下所示:

@JsonClass(generateAdapter = true)
data class Author(
    val id: Int,
    val name: String,
    val age: Int,
    val country: String
)

我确实有从here 为 ktor 安装 moshi 所需的依赖项

如果我尝试单个对象,它可能会起作用,但我需要查询输出中的整个列表。

我也尝试过按照错误提示制作自定义适配器,但它找不到我的 @ToJson 带注释的方法。

如果我使用 GSON,它会神奇地工作,但是我想弄清楚如何使用 moshi 来做到这一点。有什么想法吗?

【问题讨论】:

  • 我对 moshi 一无所知,这是一个完整的猜测,但请尝试输入 java.util.List::class.java,这样您就不会通过 Kotlin List 类型。
  • @Tenfour04 我也不太清楚你的意思,如果你正在谈论像这样adapter.toJson(result::class.java) 改变我的 toJson 调用,它不起作用。我收到Type mismatch. Required: List&lt;Author&gt;? Found: Class&lt;out List&lt;Author&gt;&gt;

标签: json kotlin parsing ktor moshi


【解决方案1】:

我发现了我的错误,这可能真的很愚蠢,但是由于 gson 的魔力,我无法弄清楚如何正确使用 moshi。真没想到还要用到适配器。

call.respond(HttpStatusCode.OK, result)

应该是:

call.respond(HttpStatusCode.OK, adapter.toJson(result))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-07
    • 1970-01-01
    • 2023-03-30
    • 2019-04-12
    相关资源
    最近更新 更多