使用Retrofit2和Gson调用OpenWeather API返回空值问题求助
我来帮你排查这个解析后返回空值的问题,结合你提到的情况——API响应正常但解析后为空,大概率是Gson字段匹配或Retrofit配置的问题,咱们一步步来理清楚:
1. 优先检查POJO字段与API响应的匹配度
这是最常见的问题!OpenWeather的API响应字段是严格大小写区分的,比如返回的"temp"、"weather"、"name"这些字段,你的POJO类必须和它们完全对应:
- 如果你的POJO字段名和API响应不一致,一定要用
@SerializedName注解指定映射关系,比如:public class Main { @SerializedName("temp") // 对应API里的"temp"字段 private double temperature; // 你的字段名可以自定义,但必须加注解 @SerializedName("humidity") private int humidity; // 其他字段... } - 特别注意嵌套结构:比如API里的
weather是一个数组,你的POJO里必须用List<Weather>来接收,不能写成单个Weather对象,否则Gson解析时会直接忽略这个字段,导致空值。
2. 确认Retrofit的Gson转换器配置正确
你必须确保Retrofit实例正确添加了Gson转换器,否则就算API返回正确JSON,也无法解析成POJO:
// 正确的Retrofit构建代码 OkHttpClient client = new OkHttpClient.Builder().build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(Api.BASE_URL) .client(client) .addConverterFactory(GsonConverterFactory.create()) // 这行必须有! .build();
另外,要确认你的项目依赖里已经添加了Gson转换器的依赖(比如Gradle里的implementation 'com.squareup.retrofit2:converter-gson:2.9.0')。
3. 检查API接口的返回类型是否正确
你的Api接口方法的返回类型必须是Call<你的根POJO类>,不能写错泛型类型,比如:
public interface Api { String api_key = "b6907d289e10d714a6e88b30761fae22"; String BASE_URL= "http://api.openweathermap.org/data/2.5/"; @GET("weather") Call<WeatherResponse> getWeather( // WeatherResponse是你的根POJO类 @Query("lat") double lat, @Query("lon") double lon, @Query("appid") String apiKey ); }
如果泛型写错成其他类,或者返回类型不是Call包裹的对象,解析后自然会是空值。
4. 验证实际API响应与POJO生成的示例是否一致
你用的是示例链接生成的POJO,但实际调用的API可能因为参数(比如units、lang)或者API版本不同,返回的JSON结构有差异。建议添加日志拦截器打印完整响应:
// 添加OkHttp日志拦截器,打印请求和响应内容 OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) .build();
然后在Logcat里找到完整的响应JSON,和你生成POJO时的示例JSON对比,看看有没有字段缺失、结构变化的情况。
5. 检查POJO的构造函数与访问修饰符
Gson需要无参构造函数来实例化POJO对象,如果你的POJO只有带参数的构造函数,Gson无法创建对象,会返回空值。另外,尽量保持字段为private(Gson默认能访问private字段),不要用protected或者package-private避免可能的访问问题。
按照这些步骤排查,基本就能找到解析空值的原因啦!
内容的提问来源于stack exchange,提问作者Anant Pundir

