Reputation: 1851
I have a class defined like this:
@JsonClass(generateAdapter = true)
data class CurrentWeather(
@Json(name = "coord") val coordinates: Coordinates,
@Json(name = "weather") val condition: List<Condition>,
@Json(name = "base") val base: String,
@Json(name = "main") val weatherCondition: Weather,
@Json(name = "wind") val windCondition: Wind,
@Json(name = "clouds") val cloudCondition: Cloud,
@Json(name = "rain") val rainCondition: Rain,
@Json(name = "snow") val snowCondition: Snow,
@Json(name = "dt") val date: Double,
@Json(name = "sys") val sysCondition: Sys,
@Json(name = "id") val cityId: Long,
@Json(name = "name") val cityName: String,
@Json(name = "cod") val status: Int
)
The problem is, while fetching my JSON data, some of these values may or may not be null. For this I had tried to append @Nullable
before the field name and/or the class name, but sadly that approach does not work. Trying with or without @Nullable
gives me the same error:
2019-11-19 16:52:37.677 1544-1544/com.a5corp.weather W/System.err: com.squareup.moshi.JsonDataException: Required value 'message' missing at $.sys
2019-11-19 16:52:37.677 1544-1544/com.a5corp.weather W/System.err: at com.squareup.moshi.internal.Util.missingProperty(Util.java:605)
2019-11-19 16:52:37.677 1544-1544/com.a5corp.weather W/System.err: at com.a5corp.weather.model.SysJsonAdapter.fromJson(SysJsonAdapter.kt:59)
2019-11-19 16:52:37.677 1544-1544/com.a5corp.weather W/System.err: at com.a5corp.weather.model.SysJsonAdapter.fromJson(SysJsonAdapter.kt:16)
2019-11-19 16:52:37.677 1544-1544/com.a5corp.weather W/System.err: at com.squareup.moshi.internal.NullSafeJsonAdapter.fromJson(NullSafeJsonAdapter.java:40)
2019-11-19 16:52:37.677 1544-1544/com.a5corp.weather W/System.err: at com.a5corp.weather.model.CurrentWeatherJsonAdapter.fromJson(CurrentWeatherJsonAdapter.kt:98)
2019-11-19 16:52:37.677 1544-1544/com.a5corp.weather W/System.err: at com.a5corp.weather.model.CurrentWeatherJsonAdapter.fromJson(CurrentWeatherJsonAdapter.kt:19)
2019-11-19 16:52:37.677 1544-1544/com.a5corp.weather W/System.err: at com.squareup.moshi.internal.NullSafeJsonAdapter.fromJson(NullSafeJsonAdapter.java:40)
2019-11-19 16:52:37.677 1544-1544/com.a5corp.weather W/System.err: at retrofit2.converter.moshi.MoshiResponseBodyConverter.convert(MoshiResponseBodyConverter.java:45)
2019-11-19 16:52:37.677 1544-1544/com.a5corp.weather W/System.err: at retrofit2.converter.moshi.MoshiResponseBodyConverter.convert(MoshiResponseBodyConverter.java:27)
2019-11-19 16:52:37.677 1544-1544/com.a5corp.weather W/System.err: at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:225)
2019-11-19 16:52:37.677 1544-1544/com.a5corp.weather W/System.err: at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:121)
2019-11-19 16:52:37.677 1544-1544/com.a5corp.weather W/System.err: at okhttp3.RealCall$AsyncCall.run(RealCall.kt:138)
2019-11-19 16:52:37.677 1544-1544/com.a5corp.weather W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
2019-11-19 16:52:37.677 1544-1544/com.a5corp.weather W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2019-11-19 16:52:37.677 1544-1544/com.a5corp.weather W/System.err: at java.lang.Thread.run(Thread.java:919)
I'm using Moshi with Retrofit in the following manner:
fun retrofit(url: String): Retrofit = Retrofit.Builder()
.client(owmClient)
.baseUrl(url)
.addConverterFactory(MoshiConverterFactory.create())
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.build()
So is there any way to accomodate Nullable values in Moshi?
EDIT 1: I have now changed my classes' so as to accomodate the solution provided by @sasikumar in the answers below, but now it gives me another new error:
2019-11-19 18:27:00.753 21530-21530/com.a5corp.weather W/System.err: java.lang.NoSuchMethodException: com.a5corp.weather.model.Condition.<init> [int, class java.lang.String, int, class kotlin.jvm.internal.DefaultConstructorMarker]
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at java.lang.Class.getConstructor0(Class.java:2332)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at java.lang.Class.getDeclaredConstructor(Class.java:2170)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at com.a5corp.weather.model.ConditionJsonAdapter.fromJson(ConditionJsonAdapter.kt:62)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at com.a5corp.weather.model.ConditionJsonAdapter.fromJson(ConditionJsonAdapter.kt:18)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at com.squareup.moshi.internal.NullSafeJsonAdapter.fromJson(NullSafeJsonAdapter.java:40)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at com.squareup.moshi.CollectionJsonAdapter.fromJson(CollectionJsonAdapter.java:76)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at com.squareup.moshi.CollectionJsonAdapter$2.fromJson(CollectionJsonAdapter.java:53)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at com.squareup.moshi.internal.NullSafeJsonAdapter.fromJson(NullSafeJsonAdapter.java:40)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at com.a5corp.weather.model.CurrentWeatherJsonAdapter.fromJson(CurrentWeatherJsonAdapter.kt:95)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at com.a5corp.weather.model.CurrentWeatherJsonAdapter.fromJson(CurrentWeatherJsonAdapter.kt:22)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at com.squareup.moshi.internal.NullSafeJsonAdapter.fromJson(NullSafeJsonAdapter.java:40)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at retrofit2.converter.moshi.MoshiResponseBodyConverter.convert(MoshiResponseBodyConverter.java:45)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at retrofit2.converter.moshi.MoshiResponseBodyConverter.convert(MoshiResponseBodyConverter.java:27)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:225)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:121)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at okhttp3.RealCall$AsyncCall.run(RealCall.kt:138)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2019-11-19 18:27:00.754 21530-21530/com.a5corp.weather W/System.err: at java.lang.Thread.run(Thread.java:919)
From the first line, I couldn't make out what it meant, but I do have my Condition
class defined like:
@JsonClass(generateAdapter = true)
data class Condition(
@Json(name = "id") val id: Int? = null,
@Json(name = "description") val description: String? = null
)
EDIT 2: It's basically the OWM API: https://openweathermap.org/current but my JSON data is here:
{
"coord": {
"lon": 77.59,
"lat": 12.98
},
"weather": [
{
"id": 802,
"main": "Clouds",
"description": "scattered clouds",
"icon": "03n"
}
],
"base": "stations",
"main": {
"temp": 26.62,
"pressure": 1015,
"humidity": 69,
"temp_min": 23,
"temp_max": 29.44
},
"visibility": 8000,
"wind": {
"speed": 3.1,
"deg": 80
},
"clouds": {
"all": 40
},
"dt": 1574169845,
"sys": {
"type": 1,
"id": 9205,
"country": "IN",
"sunrise": 1574124599,
"sunset": 1574166006
},
"timezone": 19800,
"id": 1277333,
"name": "Bengaluru",
"cod": 200
}
Upvotes: 5
Views: 4832
Reputation: 13348
For null case it should be
@JsonClass(generateAdapter = true)
data class CurrentWeather(val base: String?=null)
do all like this other nullable params.
Edit you should make data class like this for above json
data class Clouds(
val all: Int)
data class Condition(
val base: String,
val clouds: Clouds,
val cod: Int,
val coord: Coord,
val dt: Int,
val id: Int,
val main: Main,
val name: String,
val sys: Sys,
val timezone: Int,
val visibility: Int,
val weather: List<Weather>,
val wind: Wind
)
data class Coord(
val lat: Double,
val lon: Double
)
data class Main(
val humidity: Int,
val pressure: Int,
val temp: Double,
val temp_max: Double,
val temp_min: Int
)
data class Sys(
val country: String,
val id: Int,
val sunrise: Int,
val sunset: Int,
val type: Int
)
data class Weather(
val description: String,
val icon: String,
val id: Int,
val main: String
)
data class Wind(
val deg: Int,
val speed: Double
)
Upvotes: 9