缺少带有 PolymorphicJsonAdapterFactory 的标签

Missing label with PolymorphicJsonAdapterFactory

我正在尝试使用 PolymorphicJsonAdapterFactory 以获得不同的类型,但我总是遇到奇怪的异常:

Missing label for test_type

我的实体:

@JsonClass(generateAdapter = true)
data class TestResult(
    @Json(name = "test_type") val testType: TestType,
    ...
    @Json(name = "session") val session: Session,
    ...
)

这是我的 moshi 工厂:

val moshiFactory = Moshi.Builder()
    .add(
        PolymorphicJsonAdapterFactory.of(Session::class.java, "test_type")
            .withSubtype(FirstSession::class.java, "first")
            .withSubtype(SecondSession::class.java, "second")
    )
    .build()

json 响应的结构:

 {
   response: [ 
      test_type: "first",
      ...
   ]
}

test_type 必须是会话字段 class.

如果 test_type 不能在会话中 class,那么您必须为 TestResult 的每个变体声明一个 class包含具体的 Session class 如下:

sealed class TestResultSession(open val testType: String)

@JsonClass(generateAdapter = true)
data class TestResultFirstSession(
    @Json(name = "test_type") override val testType: String,
    @Json(name = "session") val session: FirstSession
) : TestResultSession(testType)

@JsonClass(generateAdapter = true)
data class TestResultSecondSession(
    @Json(name = "test_type") override val testType: String,
    @Json(name = "session") val session: SecondSession
) : TestResultSession(testType)

和您的 moshi 多态适配器:

val moshiFactory = Moshi.Builder()
    .add(
        PolymorphicJsonAdapterFactory.of(TestResultSession::class.java,"test_type")
            .withSubtype(TestResultFirstSession::class.java, "first")
            .withSubtype(TestResultSecondSession::class.java, "second")
    )
    .build()

提供回退总是好的做法,这样您的反序列化就不会失败,以防万一 test_type 未知:

@JsonClass(generateAdapter = true)
data class FallbackTestResult(override val testType: String = "")  : TestResultSession(testType)

val moshiFactory = Moshi.Builder()
    .add(
        PolymorphicJsonAdapterFactory.of(TestResultSession::class.java,"test_type")
            .withSubtype(TestResultFirstSession::class.java, "first")
            .withSubtype(TestResultSecondSession::class.java, "second")
            .withDefaultValue(FallbackTestResult())

    )
    .build()