com.google.gson.Исключение JsonSyntaxException: java.lang.Исключение IllegalStateException: Ожидался BEGIN_ARRAY, но был BEGIN_OBJECT в строке 1 столбца 148 путь $.main

#android #retrofit2 #android-room #dagger-hilt #rx-java3

Вопрос:

у меня проблема, и я действительно не знаю, как это исправить. Я пытаюсь найти похожие сообщения несколько дней, но не нашел.

Я использую доработку для анализа api, помещаю его в базу данных и использую rxjava3, потому что это будет асинхронно

Что мой JSON

 {
  "coord": {
    "lon": -0.1257,
    "lat": 51.5085
  },
  "weather": [
    {
      "id": 803,
      "main": "Clouds",
      "description": "broken clouds",
      "icon": "04d"
    }
  ],
  "base": "stations",
  "main": {
    "temp": 22.78,
    "feels_like": 22.81,
    "temp_min": 21.23,
    "temp_max": 23.92,
    "pressure": 1020,
    "humidity": 65
  },
  "visibility": 10000,
  "wind": {
    "speed": 0.45,
    "deg": 264,
    "gust": 2.68
  },
  "clouds": {
    "all": 75
  },
  "dt": 1623415339,
  "sys": {
    "type": 2,
    "id": 2019646,
    "country": "GB",
    "sunrise": 1623383015,
    "sunset": 1623442617
  },
  "timezone": 3600,
  "id": 2643743,
  "name": "London",
  "cod": 200
}
 

Служба Api

 interface OpenWeatherApiService {

@GET("weather")
fun getCurrentWeather(
    @Query("q") location:String,
    @Query("appid") key:String,
    @Query("units") units:String,
    @Query("lang") language:String = "en"
):Observable<CurrentWeatherResponse>}
 

Что мой модуль приложения

 @Module
@InstallIn(ActivityComponent::class)
object AppModule {
@Provides
fun provideOkHttpClient() =if(BuildConfig.DEBUG) {
    val interceptor = HttpLoggingInterceptor()
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
    OkHttpClient
        .Builder()
        .addInterceptor(interceptor)
        .build()
}else{
    OkHttpClient
        .Builder()
        .build()
}
@Provides
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit = Retrofit.Builder()
    .baseUrl("https:/api.openweathermap.org/data/2.5/")
    .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
    .addConverterFactory(GsonConverterFactory.create())
    .client(okHttpClient)
    .build()

@Provides
fun provideGson(): Gson = GsonBuilder().create()

@Provides
fun provideOpenWeatherApiService(retrofit: Retrofit):OpenWeatherApiService = retrofit.create(OpenWeatherApiService::class.java)

@Provides
fun provideOpenWeatherApiHelper(openWeatherApiHelper: OpenWeatherApiHelperImpl):OpenWeatherApiHelper = openWeatherApiHelper

@Provides
fun provideForecastDatabase(@ApplicationContext appContext: Context) = ForecastDatabase.getDatabase(appContext)

@Provides
fun provideCurrentWeatherDao(db: ForecastDatabase) = db.currentWeatherDao()


}
 

Мой ответ

 const val CURRENT_WEATHER_ID = 0

@Entity(tableName = "current_weather")
data class CurrentWeatherResponse(
        val main: List<Main> ,
        val name: String? = "",
        val visibility: Int? = 0,
        val weather: List<Weather> ,
        val wind:List<Wind>
){
    @PrimaryKey(autoGenerate = false)
    var id_current_weather:Int = CURRENT_WEATHER_ID
}
 

Мой конвертер типов для Main, я поместил его в базу данных

 class MainConverter {
    val gson = Gson()

    @TypeConverter
    fun listMainToString(mainList: List<Main?>?):String?{
        return gson.toJson(mainList)
    }
    @TypeConverter
    fun stringToListMain(dataMain:String?):List<Main?>?{
        if (dataMain ==  null){
            return Collections.emptyList()
        }
        val listType: Type = object :
                TypeToken<List<Main>?>() {}.type
        return gson.fromJson<List<Main?>?>(dataMain,listType)
    }
}
 

Ответ №1:

Класс данных, который вы создаете для своего ответа JSON, неверен. Многие вещи являются объектами, но вы назначили их как List предмет. Вот правильный ответ класса данных, основанный на вашем JSON. Таким образом, ответ JSON не анализируется должным образом.

 data class CurrentWeatherResponse(
    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 Clouds(
    val all: Int
)

data class Coord(
    val lat: Double,
    val lon: Double
)

data class Main(
    val feels_like: Double,
    val humidity: Int,
    val pressure: Int,
    val temp: Double,
    val temp_max: Double,
    val temp_min: Double
)

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 gust: Double,
    val speed: Double
)
 

Я предлагаю вам попробовать использовать это и попробовать еще раз. Здесь также есть плагин, который автоматически генерирует классы данных на основе JSON. Это может помочь вам больше.

https://plugins.jetbrains.com/plugin/10054-generate-kotlin-data-classes-from-json