【问题标题】:Android Retrofit - Models are GSON arrays from APIAndroid Retrofit - 模型是来自 API 的 GSON 数组
【发布时间】:2020-05-29 19:02:10
【问题描述】:

从开放天气 API 接收数据时,我收到空值。我在 android 中使用 retroFit2 来获取数据。以下是日志中的消息:

 onResponse: server response Response{protocol=http/1.1, code=200, message=OK, 
 onResponse: WeatherResponse{weather=com.weatherapp.models.Weather@197d237}

这是 GSON:

 {
"coord": {
    "lon": -5.93,
    "lat": 54.58
},
"weather": [
    {
        "id": 804,
        "main": "Clouds",
        "description": "overcast clouds",
        "icon": "04d"
    }
],
"base": "stations",
"main": {
    "temp": 293.15,
    "feels_like": 288.01,
    "temp_min": 293.15,
    "temp_max": 293.15,
    "pressure": 1024,
    "humidity": 37
},
"visibility": 10000,
"wind": {
    "speed": 5.7,
    "deg": 160
},
"clouds": {
    "all": 96
},
"dt": 1590770221,
"sys": {
    "type": 1,
    "id": 1376,
    "country": "GB",
    "sunrise": 1590724667,
    "sunset": 1590785095
},

型号

@SerializedName("coord")
@Expose
private CoOrdinateModel coOrdinateModel;

@SerializedName("weather")
@Expose
private WeatherModel[] weatherModel;

@SerializedName("main")
@Expose
private MainModel main;

@SerializedName("visibility")
@Expose
private String visibility;

@SerializedName("wind")
@Expose
private WindModel wind;

回应

 public class WeatherResponse {

@SerializedName("coord")
@Expose()
private Weather weather;

public Weather getWeather() {
    return weather;
}

@Override
public String toString() {
    return "WeatherResponse{" +
            "weather=" + weather +
            '}';
}
}

API

  @GET("/data/2.5/weather")
Call<WeatherResponse> getWeather(
        @Query("id") String ID,
        @Query("APPID") String API_KEY
);

理想情况下,我需要 GSON 中的几乎所有数据来解析为 android 应用程序中的 java 对象。我以前用更简单的 GSON 做过这个,但是这个里面有数组,我不确定我的 MODEL 类是否正确完成以适应这个。

任何帮助确定空值的根本原因将不胜感激

【问题讨论】:

    标签: android gson retrofit2


    【解决方案1】:

    您的响应模型不正确 -

    @SerializedName("main")
    @Expose
    private float main[];
    

    应该是——

    @SerializedName("main")
    @Expose
    private MainModel main;
    

    而您的 MainModel 将是您尝试解析的 POJO 类 -

    public class MainModel {
       @SerializedName("temp")
       public Double temp;
       @SerializedName("feels_like")
       public Double feelsLike;
    }
    

    对于其他人以及 wind 也可以参考,因为它们无法使用 String 类进行解析。

    【讨论】:

    • 我用您更新的建模方法更新了我的问题,请您看一下。来自服务器的响应不再返回 null 其返回:onResponse: WeatherResponse{weather=com.weatherapp.models.Weather@197d237}
    • 那么你现在还剩下什么?您只需要在您添加了private MainModel main; 的主模型类中使用getter public Weather getWeather() {return main;},您就可以访问Weather 类中的所有内容
    • 我不确定我是否认为日志中的响应应该显示正在解析的数据,它只显示 WeatherResponse{weather=com.weatherapp.models.Weather@197d237 所以我不知道它是否有效正确
    • 不,当我调用 response.body().getWeather().getMain().getTemp() 时它不起作用它由于 null 导致应用程序崩溃,因此值无法解析:(
    • Logcat 无法打印类对象WeatherResponse{weather=com.weatherapp.models.Weather@197d237 中的项目,这就是它显示为这样的原因。我猜你的问题现在是别的了。
    【解决方案2】:

    您所说的那些“数组”不是数组,它们是嵌套对象(嗯,weather 是一个对象数组,但仍然如此)。为了处理这个问题,您需要在模型类上创建嵌套类来处理嵌套对象类型,如下所示:

    public class Weather {
        public class Coordinate {
            @SerializedName("lat")
            @Expose
            public float lat;
    
            @SerializedName("long")
            @Expose
            public float long;
        }
    
        // ...
    
        @SerializedName("coord")
        @Expose
        public Coordinate coOrd;
    
        // repeat for every nested object type
    }
    

    对于weather 键,请记住这是一个对象的数组,因此模型上的字段应声明为:

    public WeatherData[] weather; // or whatever you name the nested class as
                                  // I wouldn't recommend Weather, since you've
                                  // already named your model that
    

    【讨论】:

    • 您只需像往常一样添加它们;据我所知,嵌套类不应影响您添加 cobstructors 和其他方法的能力。
    • 伙伴 我更新了问题的模型部分以显示我的新模型。响应不再返回空值,而是返回:onResponse: WeatherResponse{weather=com.weatherapp.models.Weather@197d237}
    猜你喜欢
    • 2019-06-27
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    相关资源
    最近更新 更多