调用open-meteo API时遇IllegalStateException错误求助
问题排查与解决方案
错误核心原因
java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT 是因为你的DTO数据类结构与API返回的JSON结构完全不匹配:
- API返回的顶层是一个包含
hourly对象的JSON结构,而你定义的接口返回类型WeatherDto(未提供完整定义)大概率错误地将hourly字段声明为数组类型,或者直接用WeatherDataDto作为顶层返回类(但WeatherDataDto对应是API里的hourly对象,而非整个返回体)。
具体修复步骤
1. 定义正确的顶层DTO类
根据Open-Meteo的API返回结构,你需要创建对应整个返回体的WeatherDto,里面包含hourly字段(类型为你已定义的WeatherDataDto):
data class WeatherDto( @field:SerializedName("hourly") val hourly: WeatherDataDto )
2. 修正API接口的参数冗余问题
你的@GET注解里已经硬编码了latitude=52.52&longitude=13.41,但又通过@Query传递同名参数,会导致URL出现重复参数,同时冗余的静态参数可能干扰请求。修正为:
interface WeatherApi { @GET("v1/forecast") suspend fun getWeatherData( @Query("latitude") lat: Double, @Query("longitude") long: Double, @Query("hourly") hourlyParams: String = "temperature_2m,weathercode,relativehumidity_2m,windspeed_10m,pressure_msl" ): WeatherDto }
3. 验证数据类匹配性
你的WeatherDataDto字段与API返回的hourly对象结构完全匹配,无需修改:
data class WeatherDataDto( @field:SerializedName( "time") val time: List<String>, @field:SerializedName("temperature_2m") val temperatures: List<Double>, @field:SerializedName("weathercode") val weatherCodes: List<Int>, @field:SerializedName("pressure_msl") val pressures: List<Double>, @field:SerializedName("relativehumidity_2m") val humidities: List<Double>, @field:SerializedName( "windspeed_10m") val windSpeeds: List<Double>, )
修复逻辑说明
- API返回的JSON顶层是一个对象,包含
hourly子对象,因此顶层DTOWeatherDto必须包含hourly字段(类型为对象而非数组)。 - 之前的错误是因为GSON尝试将顶层JSON对象解析为数组类型的DTO,或者直接用
WeatherDataDto(对应hourly对象)去解析整个返回体,导致类型不匹配。
内容的提问来源于stack exchange,提问作者robson idongesit samuel
相关产品推荐
相关产品推荐

