4

I've very less experience with Json and I've to parse a complex Json to Java Objects.

I've tried several approaches without success... I'm getting a weather forecast for my city in Json format and I need to parse that Json data into Java Objects.

The Json:

{"city":
 {"city_code":"ATAT10678",
  "name":"Wien",
  "url":"oesterreich/wien/ATAT10678.html",
  "credit":{"info":"In order to use the free weather data from wetter.com you HAVE TO display at least two out of three of the following possibilities: text, link, logo",
  "text":"Powered by wetter.com","link":"http://www.wetter.com",
  "logo":"Download at http://www.wetter.com/api/downloads/#logos"},
  "forecast":{
   "2014-08-24":{
    "w":"1",
    "tx":"20",
    "pc":"30",
    "06:00":{
     "w":"2",
     "tx":"16",
     "pc":"30",
     "tn":"15",
     "p":"5",
     "dhl":"2014-08-24 06:00",
     "ws":"19",
     "w_txt":"wolkig"},
    "11:00":{
     "w":"2",
     "tx":"18",
     "pc":"30",
     "tn":"16",
     "p":"6",
     "dhl":"2014-08-24 11:00",
     "ws":"20",
     "w_txt":"wolkig"},
    "17:00":{
     "w":"1",
     "tx":"20",
     "pc":"20",
     "tn":"16",
     "p":"6",
     "dhl":"2014-08-24 17:00",
     "ws":"12",
     "w_txt":"leicht bewölkt"},
    "23:00":{
     "w":"1",
     "tx":"16",
     "pc":"10",
     "tn":"13",
     "p":"6",
     "dhl":"2014-08-24 23:00",
     "ws":"7",
     "w_txt":"leicht bewölkt"},
    "tn":"15",
    "p":"24",
    "dhl":"2014-08-24 06:00",
    "ws":"14",
    "w_txt":"leicht bewölkt"},
   "2014-08-25":{"w":"2","tx":"22","pc":"30","06:00":{"w":"2","tx":"17","pc":"20","tn":"12","p":"5","dhl":"2014-08-25 06:00","ws":"5","w_txt":"wolkig"},"11:00":{"w":"2","tx":"21","pc":"30","tn":"17","p":"6","dhl":"2014-08-25 11:00","ws":"10","w_txt":"wolkig"},"17:00":{"w":"2","tx":"22","pc":"30","tn":"18","p":"6","dhl":"2014-08-25 17:00","ws":"11","w_txt":"wolkig"},"23:00":{"w":"3","tx":"18","pc":"30","tn":"16","p":"6","dhl":"2014-08-25 23:00","ws":"6","w_txt":"bedeckt"},"tn":"12","p":"24","dhl":"2014-08-25 06:00","ws":"8","w_txt":"wolkig"},"2014-08-26":{"w":"3","tx":"22","pc":"75","06:00":{"w":"3","tx":"17","pc":"75","tn":"15","p":"5","dhl":"2014-08-26 06:00","ws":"6","w_txt":"bedeckt"},"11:00":{"w":"61","tx":"21","pc":"75","tn":"17","p":"6","dhl":"2014-08-26 11:00","ws":"9","w_txt":"leichter Regen"},"17:00":{"w":"61","tx":"22","pc":"75","tn":"18","p":"6","dhl":"2014-08-26 17:00","ws":"9","w_txt":"leichter Regen"},"23:00":{"w":"3","tx":"18","pc":"75","tn":"17","p":"6","dhl":"2014-08-26 23:00","ws":"9","w_txt":"bedeckt"},"tn":"15","p":"24","dhl":"2014-08-26 06:00","ws":"8","w_txt":"bedeckt"}}}}

I've no idea how I can parse this to objects..

Many thanks for the advices!

Here is my first trial..

        Gson gson = new Gson();
        JsonObject jsonObj = gson.fromJson(br, JsonObject.class);
        Map<String, LinkedTreeMap> map = new HashMap<String, LinkedTreeMap>();
        map = (Map<String, LinkedTreeMap>) gson.fromJson(jsonObj.toString(), map.getClass());

        LinkedTreeMap<String, LinkedTreeMap> tmp = new LinkedTreeMap<>();
        tmp = map.get("city");

        for(Map.Entry<String, LinkedTreeMap> e : tmp.entrySet()) {
            System.out.println("k: " + e.getKey());
        }

        LinkedTreeMap<String, LinkedTreeMap> tmp1 = new LinkedTreeMap<>();
        tmp1 = tmp.get("forecast");

        for(Map.Entry<String, LinkedTreeMap> e : tmp1.entrySet()) {
            System.out.println("k: " + e.getKey());
            LinkedTreeMap<String, LinkedTreeMap> values = e.getValue();
            for(Map.Entry<String, LinkedTreeMap> v : values.entrySet()) {

                System.out.println("k: " + v.getKey() + " v: " + v.getValue());
            }

        }

and the output for one day:

k: city_code
k: name
k: url
k: credit
k: forecast
k: 2014-08-25
k: w v: 2
k: tx v: 23
k: pc v: 90
k: 06:00 v: {w=2, tx=17, pc=20, tn=13, p=5, dhl=2014-08-25 06:00, ws=5, w_txt=wolkig}
k: 11:00 v: {w=2, tx=21, pc=20, tn=17, p=6, dhl=2014-08-25 11:00, ws=9, w_txt=wolkig}
k: 17:00 v: {w=2, tx=23, pc=30, tn=17, p=6, dhl=2014-08-25 17:00, ws=11, w_txt=wolkig}
k: 23:00 v: {w=3, tx=17, pc=90, tn=16, p=6, dhl=2014-08-25 23:00, ws=6, w_txt=bedeckt}
k: tn v: 13
k: p v: 24
k: dhl v: 2014-08-25 06:00
k: ws v: 8
k: w_txt v: wolkig

so far so good but how I get the 06:00, 11:00, 17:00 and 23:00 (generic because the time can be changed) because this are the informations I need?

Thanks a lot and BR typhon

typhon
  • 73
  • 1
  • 1
  • 7
  • 1
    what have you tried till now? look at GSOn library from google.https://code.google.com/p/google-gson/ – Adi Aug 24 '14 at 18:27
  • Parse with Gson but I can't access the dynamic attribute "2014-08-24": in forecasts. – typhon Aug 24 '14 at 19:05
  • I have answered the solution here http://stackoverflow.com/a/15943171/441902 – Tito Mar 07 '17 at 14:26

5 Answers5

4

Here is an example using GSON

import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
public class CodeChefTest1 {
    public static String json = "{\"balance\": 1000.21, \"num\":100, \"is_vip\":true, \"name\":\"foo\"}";
    public static void main(String[] args) {
        JsonElement ele = new JsonParser().parse(json);
        for(java.util.Map.Entry<String, JsonElement> entr : ele.getAsJsonObject().entrySet()){
            System.out.println(entr.getKey());
            System.out.println(entr.getValue());
        }
    }
}

You can use the above and run it in a loop using checks on the JSONElements like isJSONArray(),isJSONObject(),isJSONPrimitive() etc and perform suitable re-parsing using the same strategy.

The above just iterates over the json string and prints all the key value pairs. You can do the same for the date part of your json string.

Sumeet Sharma
  • 2,573
  • 1
  • 12
  • 24
  • I've tried already but I can't access the attribute "2014-08-24": in forecasts because it is variable – typhon Aug 24 '14 at 19:04
2

I personally recommend using jackson. With jackson you can translate JSON strings to POJOs (java beans). https://github.com/FasterXML/jackson

This library is free, fast and easy to work with.

Since you have dates and times as property names, I think that at least that part of your object should be a JAVA map, as Amaynut suggested.

galusben
  • 5,948
  • 6
  • 33
  • 52
1

In addition to gba's Jackson, you can use Google GSON: https://code.google.com/p/google-gson/

Also, check out this thread: Jackson Vs. Gson

Community
  • 1
  • 1
Renat Bekbolatov
  • 329
  • 4
  • 11
1

You can use the library Gson from google. Here's an example of a json object converted to Java object of type Map:

 Gson gson=new Gson(); 
String json="{\"k1\":\"v1\",\"k2\":\"v2\"}";
Map<String,String> map=new HashMap<String,String>();
map=(Map<String,String>) gson.fromJson(json, map.getClass());

Another solution to try with Gson library is the following:

Gson gson = new Gson();
String json="{\"k1\":\"v1\",\"k2\":\"v2\"}";
LinkedTreeMap result = gson.fromJson(json, LinkedTreeMap.class);

You need to import these two classes:

import com.google.gson.Gson;
import com.google.gson.internal.LinkedTreeMap;

You can check this post about the same subject: How can I convert JSON to a HashMap using Gson?

Community
  • 1
  • 1
Amaynut
  • 4,091
  • 6
  • 39
  • 44
  • I've tried you advice: Gson gson = new Gson(); JsonObject jsonObj = gson.fromJson(br, JsonObject.class); Map map = new HashMap(); map = (Map) gson.fromJson(jsonObj.toString(), map.getClass()); for(Map.Entry e : map.entrySet()) { System.out.println("k: " + e.getKey() + " v: " + e.getValue()); } But I get a java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to java.lang.String? – typhon Aug 24 '14 at 19:07
  • In your case I think you have to put **Map** instead of **Map**. Try and tell us if it works. – Amaynut Aug 24 '14 at 19:12
0

this is the first working code.. (quick 'n dirty)..

Thx to Sumeet Sharma! Maybe somebody have a nicer solution...

    public void updateWeather() {
    forecasts = new ArrayList<>();
    try  {

        URL url = new URL(createURL());
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);

        OutputStream os = conn.getOutputStream();
        os.flush();

        if (conn.getResponseCode() != 200) {
            throw new RuntimeException("Failed : HTTP error code : "
                    + conn.getResponseCode());
        }

        BufferedReader br = new BufferedReader(new InputStreamReader(
                (conn.getInputStream())));

        Gson gson = new Gson();
        JsonObject jsonObj = gson.fromJson(br, JsonObject.class);

        JsonElement element = jsonObj.get("city");
        jsonObj = gson.fromJson(element.getAsJsonObject(), JsonObject.class);
        element = jsonObj.get("forecast");

        for (Map.Entry<String, JsonElement> entr : element.getAsJsonObject().entrySet()) {
            JsonElement element1 = entr.getValue().getAsJsonObject();
            for (Map.Entry<String, JsonElement> entr1 : element1.getAsJsonObject().entrySet()) {
                if (entr1.getValue().isJsonObject()) {
                    JsonElement element2 = entr1.getValue().getAsJsonObject();
                    Forecast forecast = new Forecast();
                    for (Map.Entry<String, JsonElement> entr2 : element2.getAsJsonObject().entrySet()) {
                        switch (entr2.getKey()) {
                            case "w":
                                forecast.setW(entr2.getValue().getAsString());
                                break;
                            case "tx":
                                forecast.setTx(entr2.getValue().getAsString());
                                break;
                            case "pc":
                                forecast.setPc(entr2.getValue().getAsString());
                                break;
                            case "tn":
                                forecast.setTn(entr2.getValue().getAsString());
                                break;
                            case "p":
                                forecast.setP(entr2.getValue().getAsString());
                                break;
                            case "dhl":
                                forecast.setDhl(entr2.getValue().getAsString());
                                break;
                            case "ws":
                                forecast.setWs(entr2.getValue().getAsString());
                                break;
                            case "w_txt":
                                forecast.setW_txt(entr2.getValue().getAsString());
                                break;
                        }
                    }
                    forecasts.add(forecast);
                }
            }
        }
        conn.disconnect();

    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    for(Forecast f : forecasts)
        System.out.println(f);
}
typhon
  • 73
  • 1
  • 1
  • 7