1

I'm parsing json data from OpenWeathermap.org which is like this :

{
   "cod":"200",
"message":0.0016,
"city":{
  "id":1164408,
  "name":"Sukkur",
  "coord":{
     "lon":68.857384,
     "lat":27.70516
  },
  "country":"PK",
  "population":0,
  "sys":{
     "population":0
  }  },  

"cnt":2,
"list":[
  {
     "dt":1394175600,
     "temp":{
        "day":26.31,
        "min":20,
        "max":30.17,
        "night":22.71,
        "eve":30.17,
        "morn":20
     },
     "pressure":1024.11,
     "humidity":59,
     "weather":[
        {
           "id":801,
           "main":"Clouds",
           "description":"few clouds",
           "icon":"02d"
        }
     ],
     "speed":0.91,
     "deg":121,
     "clouds":12
  },
  {
     "dt":1394262000,
     "temp":{
        "day":25.58,
        "min":18.94,
        "max":28.22,
        "night":21.08,
        "eve":28.22,
        "morn":18.94
     },
     "pressure":1026.39,
     "humidity":58,
     "weather":[
        {
           "id":800,
           "main":"Clear",
           "description":"sky is clear",
           "icon":"01d"
        }
     ],
     "speed":5.75,
     "deg":74,
     "clouds":0
  }
]}

after looking at thisSO Question, I made my Model.java class for above json data as

public class Model{

protected String cityId = null;
protected String cityName = null;
protected String countryName = null;
protected String longitude = null;
protected String latitude = null;
protected String polution = null;
protected List<ForecatList> forcastList = null;
// getters setters
public class ForecatList {
    protected String dayTimeTemp = null;
    protected String maxTemp = null;
    protected String minTemp = null;
    protected String nightTimeTemp = null;
    protected String eveTimeTemp = null;
    protected String mornTimeTemp = null;
    protected String pressure = null;
    protected String humidity = null;
    protected String windSpeed = null;
    protected String WindDegree = null;
    protected String clouds = null;
    protected List<Weather> weathers = null;
    // getters setters
    public class Weather {
        protected String weatherId = null;
        protected String weatherCondition = null;
        protected String weatherDescription = null;
        protected String weatherIcon = null;
        // getters setters
    }
}}

parsing profess is :

public Model getForecastByCityName(Context context, String city, int ofDays){
    Model model = null;     
    try {           
        Gson gson = new Gson();
        Reader reader = new InputStreamReader(forecastByCityName(context, city, ofDays));           
        model = gson.fromJson(reader, Model.class);         
        return model;
    } catch (ClientProtocolException e) {
        e.printStackTrace();
        return null;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }   
}

and forecastByCityName() is :

private InputStream forecastByCityName(Context context, String city, int ofDays) throws ClientProtocolException, IOException{
    HttpClient httpClient = null;
    StringBuilder url = new StringBuilder(URL_FORCAST);
    url.append(city);
    url.append(String.valueOf(ofDays));
    url.append(UNIT);
    HttpGet httpRequest = new HttpGet(url.toString());
    httpClient = new DefaultHttpClient();
    HttpResponse httpResponse = httpClient.execute(httpRequest);
    int statusCode = httpResponse.getStatusLine().getStatusCode();
    if (statusCode == 200) {
        HttpEntity httpEntity = httpResponse.getEntity();
        return httpEntity.getContent();
    }else {
        return null;            
    }       
}

my request is successful, but when I try to get values from Model object like :

textView.setText(model.getCityName() + model.getCountryName());                             

that prints null null null, why that fails to get values? any idea..

Community
  • 1
  • 1
Arshad Ali
  • 3,082
  • 12
  • 56
  • 99

3 Answers3

4
  1. All field names in Model class must be equal json keys: for "country" - protected String country;
  2. "city" json key has its own inner data, so you need to create City class with appropriate field names and to define 'protected City city;' field in your Model class.

Here all you need (100 % works on your json-example):

public class Model implements Serializable {

private String cod;
private Double message;
private City city;
private Integer cnt;
private List<ListItem> list = new ArrayList<ListItem>();

public String getCod() {
    return cod;
}

public void setCod(String cod) {
    this.cod = cod;
}

public Double getMessage() {
    return message;
}

public void setMessage(Double message) {
    this.message = message;
}

public City getCity() {
    return city;
}

public void setCity(City city) {
    this.city = city;
}

public Integer getCnt() {
    return cnt;
}

public void setCnt(Integer cnt) {
    this.cnt = cnt;
}

public List<ListItem> getList() {
    return list;
}

public void setList(List<ListItem> list) {
    this.list = list;
}

private class City implements Serializable { 
    private Integer id;
    private String name;
    @SerializedName("coord")
    private Coordinates coordinates;
    private String country;
    private Integer population;
    private Sys sys;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Coordinates getCoordinates() {
        return coordinates;
    }

    public void setCoordinates(Coordinates coordinates) {
        this.coordinates = coordinates;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public Integer getPopulation() {
        return population;
    }

    public void setPopulation(Integer population) {
        this.population = population;
    }

    public Sys getSys() {
        return sys;
    }

    public void setSys(Sys sys) {
        this.sys = sys;
    }

    private class Coordinates implements Serializable {
        @SerializedName("lon")
        private Double longitude;
        @SerializedName("lat")
        private Double latitude;

        public Double getLongitude() {
            return longitude;
        }

        public void setLongitude(Double longitude) {
            this.longitude = longitude;
        }

        public Double getLatitude() {
            return latitude;
        }

        public void setLatitude(Double latitude) {
            this.latitude = latitude;
        }
    }

    private class Sys implements Serializable {
        private Integer population;

        public Integer getPopulation() {
            return population;
        }

        public void setPopulation(Integer population) {
            this.population = population;
        }
    }
}

private class ListItem implements Serializable {
    @SerializedName("dt")
    private Long dateTime;
    @SerializedName("temp")
    private Temperature temperature;
    private Double pressure;
    private Integer humidity;
    private List<Weather> weather = new ArrayList<Weather>();
    private Double speed;
    @SerializedName("deg")
    private Integer degree;
    private Integer clouds;

    public Long getDateTime() {
        return dateTime;
    }

    public void setDateTime(Long dateTime) {
        this.dateTime = dateTime;
    }

    public Temperature getTemperature() {
        return temperature;
    }

    public void setTemperature(Temperature temperature) {
        this.temperature = temperature;
    }

    public Double getPressure() {
        return pressure;
    }

    public void setPressure(Double pressure) {
        this.pressure = pressure;
    }

    public Integer getHumidity() {
        return humidity;
    }

    public void setHumidity(Integer humidity) {
        this.humidity = humidity;
    }

    public List<Weather> getWeather() {
        return weather;
    }

    public void setWeather(List<Weather> weather) {
        this.weather = weather;
    }

    public Double getSpeed() {
        return speed;
    }

    public void setSpeed(Double speed) {
        this.speed = speed;
    }

    public Integer getDegree() {
        return degree;
    }

    public void setDegree(Integer degree) {
        this.degree = degree;
    }

    public Integer getClouds() {
        return clouds;
    }

    public void setClouds(Integer clouds) {
        this.clouds = clouds;
    }

    private class Temperature implements Serializable {
        private Double day;
        private Double min;
        private Double max;
        private Double night;
        @SerializedName("eve")
        private Double evening;
        @SerializedName("morn")
        private Double morning;

        public Double getDay() {
            return day;
        }

        public void setDay(Double day) {
            this.day = day;
        }

        public Double getMin() {
            return min;
        }

        public void setMin(Double min) {
            this.min = min;
        }

        public Double getMax() {
            return max;
        }

        public void setMax(Double max) {
            this.max = max;
        }

        public Double getNight() {
            return night;
        }

        public void setNight(Double night) {
            this.night = night;
        }

        public Double getEvening() {
            return evening;
        }

        public void setEvening(Double evening) {
            this.evening = evening;
        }

        public Double getMorning() {
            return morning;
        }

        public void setMorning(Double morning) {
            this.morning = morning;
        }
    }

    private class Weather implements Serializable {
        private Integer id;
        private String main;
        private String description;
        private String icon;

        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        public String getMain() {
            return main;
        }

        public void setMain(String main) {
            this.main = main;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public String getIcon() {
            return icon;
        }

        public void setIcon(String icon) {
            this.icon = icon;
        }
    }
}

}

DmitryKanunnikoff
  • 2,226
  • 2
  • 22
  • 35
  • thanks for your response, will `ListItem` class fetch data of all/multiple child objects? – Arshad Ali Mar 07 '14 at 17:33
  • Do not mention it. This code should work on any amount of data without any restrictions. – DmitryKanunnikoff Mar 07 '14 at 18:47
  • I'm getting `NullPointerException` while trying to populate an `ArrayAdpter` like this http://pastebin.com/9HEg3eAq, please tell how to get data from there. – Arshad Ali Mar 08 '14 at 05:19
  • Try to use android.util.Log class where possible. And show, please, WeatherForecastInfo and WeatherForecastInfo.ListItem code. – DmitryKanunnikoff Mar 08 '14 at 08:37
  • I have just replaced the class name from `Model` to `WeatherForecastInfo`, all the other stuff is the same as yours – Arshad Ali Mar 08 '14 at 13:05
  • In this case you need write something like result.getList().get(i).getWeather(), where i - index of some ListItem object in the list. – DmitryKanunnikoff Mar 08 '14 at 13:13
  • Ok now I'm getting data but like`com.example.android...`, how to get to convert that in readable `String` form? – Arshad Ali Mar 08 '14 at 13:22
  • Ok I have got idea it is only to override the `toString()`, method, thanks alot for your time... – Arshad Ali Mar 08 '14 at 13:30
  • Are you talking about result.getList().get(i).getWeather() ? To get some real data from this object you need call its methods: result.getList().get(i).getWeather().getIcon() - for getting of icon, for example. – DmitryKanunnikoff Mar 08 '14 at 14:18
2

I would suggest you automate your model creation using some tool. I personally use http://www.jsonschema2pojo.org/ all the time.

Amol Gupta
  • 704
  • 1
  • 8
  • 26
  • thanks for your consideration, may I ask you that is there an alternate way for parsing that through simple `json parsing`? – Arshad Ali Mar 07 '14 at 08:14
  • havent tried yet... but using this model generator and parsing using GSON has been the quickest for me. – Amol Gupta Mar 07 '14 at 08:16
2

Your POJO isn't quite right for the JSON output. You need to create a city object for Gson to catch the city data. To get the city and country name you need to do the following;

public class Model {
    private String cod;
    private City city;

    // To catch the forecasts list
    private List<ForecastList> list;

    // Alternatively if you want the variable to be called forecastList
    // you can do the following
    @SerializedName("list")
    private List<ForecastList> forecastList;

    public class City {
        private String name;
        private String country;

        public String getName() {
            return name;
        }

        public String getCountry() {
            return country;
        }
    }

    public City getCity() {
        return city;
    }

    // Omitted for brevity
}

You can then get the city and country name by doing the following;

Gson gson = new Gson();
Reader reader = new InputStreamReader(forecastByCityName(context, city, ofDays));           
Model model = gson.fromJson(reader, Model.class);
String cityName = model.getCity().getName();
String cityCountry = model.getCity().getCountry();

Or if you wish you could make some encapsulating methods on Model for convenience.

marcus.ramsden
  • 2,633
  • 1
  • 22
  • 33
  • thanks Man, now that gives me data, but One thing I want to ask that will the list also be populated or I have to loop through to set that? – Arshad Ali Mar 07 '14 at 08:36
  • If you mean the list property, gson should be populating that for you if you change the forecastList field to be called list. I've updated my example to show this. – marcus.ramsden Mar 07 '14 at 08:45
  • I'm getting NullPointerException while trying to populate an ArrayAdpter like this http://pastebin.com/E0PYcnn3, please tell how to get data from there. – – Arshad Ali Mar 08 '14 at 05:25