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

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

5 Answers 5

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I've tried already but I can't access the attribute "2014-08-24": in forecasts because it is variable
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.

Comments

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

Comments

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?

2 Comments

I've tried you advice: Gson gson = new Gson(); JsonObject jsonObj = gson.fromJson(br, JsonObject.class); Map<String, String> map = new HashMap<String, String>(); map = (Map<String, String>) gson.fromJson(jsonObj.toString(), map.getClass()); for(Map.Entry<String, String> 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?
In your case I think you have to put Map<String, Object> instead of Map<String, String>. Try and tell us if it works.
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);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.