5

我将kotlinx.serialization与 retrofit 结合使用。我收到的 json 响应将根据它包含的属性而有所不同。在大多数情况下,我的应用程序中的数据模型包含的字段比我在响应中收到的要多。我无法控制它,所以我需要在代码中处理它。

MissingFieldException在这种情况下,Kotlinx.serialization 会抛出 a 。我知道在使用时Json.parse您可以将其包装在 try-catch 块中并忽略此类错误。但由于我使用的是改造,我看不到使用这种方法的方法:

网络服务.kt

interface WebService {
    @GET("person.json")
    fun getPerson(): Call<MainActivity.Person>
}

MainActivity.kt

class MainActivity : AppCompatActivity() {

    @Serializable
    data class Person(val name: String, val species: String, val missing: String)

    @UnstableDefault
    override fun onCreate(savedInstanceState: Bundle?) {
        val mediaType = "application/json".toMediaTypeOrNull()
        mediaType?.let {
            retrofit = Retrofit.Builder()
                .addConverterFactory(Json.nonstrict.asConverterFactory(it))
                .baseUrl(baseUrl)
                .build()
        }

        webService = retrofit.create(WebService::class.java)

        GlobalScope.launch {
            val person = fetchPerson(webService)
        }
    }

    private suspend fun fetchPerson(webService: WebService): Person {
        return suspendCancellableCoroutine { cont ->
            webService.getPerson()
                .enqueue(object : Callback<Person> {
                    override fun onFailure(call: Call<Person>, t: Throwable) {
                        Log.e(t.toString(), "Unable to get api response")
                        cont.cancel(t)
                    }

                    override fun onResponse(
                        call: Call<Person>,
                        response: Response<Person>
                    ) {
                        if (response.isSuccessful) {
                            response.body()?.let { cont.resume(it) }
                        } else {
                            cont.cancel(IOException("${response.code()}: ${response.errorBody()}"))
                        }
                    }
                })
        }
    }
}

json 响应(在这个组成的示例中)故意省略了“缺失”字段:

{"name":"me", "species":"superhuman"}

由于该 json 不包含missing数据类中的字段,因此应用程序崩溃并抛出MissingFieldException. 我想知道如何在改造案例中避免这个问题。

谢谢你的帮助。

4

2 回答 2

12

实际上它不能Person从 json 创建对象,因为您的Person类构造函数需要 3 个值。您必须满足此要求才能创建对象。

解决此问题的一种可能解决方案是在Kotlin中使用默认值,如下所示:

data class Person(
    var name: String="", 
    var species: String="", 
    var missing: String="") 

另一种解决方案是使用具有不同参数的多个构造函数,但由于您提到它可能会随着时间的推移而有所不同,因此该解决方案可能并不方便。谢谢

于 2019-10-11T02:33:53.510 回答
0

从 开始kotlinx.serialization-1.3.0,您可以将 Json 对象创建为Json { explicitNulls = false }. 这将有助于序列化具有不同字段的响应,而无需抛出MissingFieldException和不需要传递默认值。

参考

于 2021-09-28T17:35:56.107 回答