使用Retrofit2解析OpenWeatherMap API时获取Null值问题
解决Retrofit解析OpenWeatherMap API时lat/lon返回Null的问题
嘿,我一眼就看出问题所在啦——你没注意到OpenWeatherMap的API响应里,lat和lon是嵌套在coord对象里面的,而你的模型类直接把这两个字段放在了顶层,Gson根本找不到对应的映射关系,所以才会返回Null。
先看API的实际响应结构(简化版)
{
"coord": {
"lat": 35.0844,
"lon": -85.3097
},
"weather": [...],
// 其他无关字段省略
}
解决方案:调整模型类匹配JSON结构
你需要创建一个顶层的响应类,用来包裹整个API返回的内容,其中包含嵌套的coord对象:
// 顶层响应类,对应完整的API返回JSON public class WeatherResponse { // 对应响应里的coord字段 private CoordObject coord; public CoordObject getCoord() { return coord; } // 内部类,专门映射coord里的lat和lon public static class CoordObject { // 注意:API返回的是数值类型,用double比String更合适 private double lat; private double lon; public double getLat() { return lat; } public double getLon() { return lon; } } }
更新Retrofit接口
把接口的返回类型改成我们新创建的WeatherResponse:
public interface OwmInterface { @GET("/data/2.5/weather") Call<WeatherResponse> getWeatherData(@Query("q") String zipCode, @Query("appid") String appId); }
修改Activity里的回调逻辑
现在需要从顶层响应里取出嵌套的coord对象,同时增加空值检查避免崩溃:
final String BASE_URL = "https://api.openweathermap.org/"; final String API_KEY_OWM = "xxxx"; Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); OwmInterface request = retrofit.create(OwmInterface.class); Call<WeatherResponse> call = request.getWeatherData( "37421", API_KEY_OWM ); call.enqueue(new Callback<WeatherResponse>() { @Override public void onResponse(Call<WeatherResponse> call, Response<WeatherResponse> response){ // 先检查响应是否成功、响应体是否为空 if (response.isSuccessful() && response.body() != null) { WeatherResponse.CoordObject coord = response.body().getCoord(); if (coord != null) { // 把double转成String显示Toast Toast.makeText(MainActivity.this, String.valueOf(coord.getLat()), Toast.LENGTH_LONG).show(); Toast.makeText(MainActivity.this, String.valueOf(coord.getLon()), Toast.LENGTH_LONG).show(); } else { Toast.makeText(MainActivity.this, "坐标数据缺失", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(MainActivity.this, "请求响应失败", Toast.LENGTH_SHORT).show(); } } @Override public void onFailure(Call<WeatherResponse> call, Throwable t) { // 打印具体错误信息方便调试 Toast.makeText(MainActivity.this, "请求失败: " + t.getMessage(), Toast.LENGTH_SHORT).show(); } });
额外的小建议
- 字段类型匹配:API返回的
lat和lon是浮点数,用double类型比String更合理,避免后续类型转换的麻烦。 - 调试技巧:如果还是有问题,可以在
onResponse里打印响应的原始内容,确认JSON结构是否符合预期:Log.d("API_RESPONSE", response.raw().toString()); // 或者打印完整响应体字符串 if (response.body() != null) { Log.d("API_BODY", new Gson().toJson(response.body())); }
内容的提问来源于stack exchange,提问作者seekingStillness
相关产品推荐
相关产品推荐

