Json:我如何确定一个字段是否存在?

rbpvctlc  于 2023-02-26  发布在  其他
关注(0)|答案(1)|浏览(177)

利用kotlin序列化技术,实现了从openweathermap获取JSON数据的过程。
在任何给定的日子,例如下雨或下雪,场可能存在或可能不存在。
执行以下代码时出错
WeatherResponse.kt

@SerialName("WeatherData")
@Serializable
data class WeatherResponse(
    val list: List<WeatherEntry>
)

@SerialName("WeatherEntry")
@Serializable
data class WeatherEntry(
    val main: MainData,
    val weather: List<Weather>,
    val wind: Wind,
    val pop: Double,
    val sys: Sys,
    val dt_txt: String,
    val rain: Rain,
    val snow: Snow,
)

@SerialName("Rain")
@Serializable
data class Rain(
    val three_hour_rain: Double = 0.0,
)

@SerialName("Snow")
@Serializable
data class Snow(
    val three_hour_snow: Double = 0.0,
)

testFragment.kt

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        sharedViewModel.data.observe(viewLifecycleOwner) { data ->
            val weatherResponse = json.decodeFromString<WeatherResponse>(data)

            binding.apply {
                rainText.text = weatherResponse.list[0].rain.three_hour_rain.toString() + "mm"
                snowText.text = weatherResponse.list[0].snow.three_hour_snow.toString() + "mm"

            }
        }
    }

kotlinx.序列化.缺少字段异常:序列名为“WeatherEntry”的类型需要字段“rain”,但缺少该字段

我应该在什么时候确定是否在JSON中生成雨(雪)数据?
我尝试允许数据类rain为null,three_rain_hour,但没有成功。
之后,我注意到数据本身并没有生成
我已经在JsonBuilder中指定了ignoreUnknownKeys = true

i7uq4tfw

i7uq4tfw1#

您看到的错误表明,至少有一个WeatherEntry对象的JSON数据中缺少rain字段,这是因为Rain类不可为空,因此WeatherEntry类中的rain属性被标记为必需。
要处理JSON数据中可能不存在rain(或snow)字段的情况,可以通过在RainSnow类的类名后面添加问号,使它们可以为空,如下所示:

@SerialName("Rain")
@Serializable
data class Rain(
    val three_hour_rain: Double? = null,
)

@SerialName("Snow")
@Serializable
data class Snow(
    val three_hour_snow: Double? = null,
)

这样,如果JSON数据中缺少rainsnow字段,它将被反序列化为null。
但是,如果您仍然希望RainSnow类不可为空,则可以使用Json.default对象为WeatherEntry类中的RainSnow属性提供默认值,如下所示:

@SerialName("WeatherEntry")
@Serializable
data class WeatherEntry(
    val main: MainData,
    val weather: List<Weather>,
    val wind: Wind,
    val pop: Double,
    val sys: Sys,
    val dt_txt: String,
    val rain: Rain = Json.default.decodeFromString("{}"),
    val snow: Snow = Json.default.decodeFromString("{}"),
)

这里,我们使用Json.default.decodeFromString方法提供一个空JSON对象({})作为rainsnow属性的默认值,这样,如果JSON数据中缺少rainsnow字段,它将被反序列化为空对象,而不是抛出MissingFieldException
关于何时确定rainsnow数据是否存在于JSON中的问题,可以在WeatherEntry对象中访问RainSnow对象的属性之前检查它们是否为空,如下所示:

val rainTextValue = weatherResponse.list[0].rain?.three_hour_rain?.toString() ?: "N/A"
val snowTextValue = weatherResponse.list[0].snow?.three_hour_snow?.toString() ?: "N/A"
binding.rainText.text = "$rainTextValue mm"
binding.snowText.text = "$snowTextValue mm"

这里,我们使用安全调用运算符(?.)访问three_hour_rainthree_hour_snow属性,如果RainSnow对象为空,则使用Elvis运算符(?:)提供默认值“N/A”。

相关问题