0

I just need a quick advice, as i am a total beginner with JSON.

I get the following response from a webserver, which i store in a String:

{  
   "station62":[  
      {  
         "departureTime":1982,
         "delay":"-1.0",
         "line":"6",
         "stationName":"randomname",
         "direction":2
      }
   ],
   "station63":[  
      {  
         "departureTime":1234,
         "delay":"-1.0",
         "line":"87",
         "stationName":"anotherrandomname",
         "direction":2
      }
   ],
   "station64":[  
      {  
         "departureTime":4542,
         "delay":"-1.0",
         "line":"4",
         "stationName":"yetanotherrandomname",
         "direction":2
      }
   ],
   "station65":[  
      {  
         "departureTime":1232,
         "delay":"-1.0",
         "line":"23",
         "stationName":"onemorerandomname",
         "direction":2
      }
   ]
}

(Sorry, i dont know how the indent works on here.)

The response is longer, but for this example it is shortened. So what i need is to parse the information of each of these "station"-objects. I dont need the "station62"-String, i only need "departureTime", "delay", "line", "stationName" and "direction" in a java-object.

I have read this, but i couldnt make it work: https://stackoverflow.com/a/16378782

I am a total beginner, so any help would be really appreciated.

Edit: Here is my code:

I made a wrapper class just like in the example link above. I played with the map types a bit, but no luck so far.

public class ServerResponse
{

private Map<String, ArrayList<Station>> stationsInResponse = new HashMap<String, ArrayList<Station>>();

public Map<String, ArrayList<Station>> getStationsInResponse()
{
    return stationsInResponse;
}

public void setStationsInResponse(Map<String, ArrayList<Station>> stationsInResponse)
{
    this.stationsInResponse = stationsInResponse;
}
}

The problem is, that this map does not get filled by the gson.fromJSON(...)-call i am showing below. The map size is always zero.

Station class looks like this:

public class Station
{
String line;
String stationName;
String departureTime;
String direction;
String delay;

// getters and setters are there aswell
}

And what i am trying to do is

Gson gson = new Gson();
ServerResponse response = gson.fromJson(jsonString, ServerResponse.class);

where "jsonString" contains the JSON response as a string.

I hope that code shows what i need to do, it should be pretty simple but i am just not good enough in JSON.

EDIT 2

Would i need my JSON to be like this?

{"stationsInResponse": {
"station62": [{
    "departureTime": 1922,
    "delay": "-1.0",
    "line": "8",
    "stationName": "whateverrandomname",
    "direction": 2
  }],
"station67": [{
    "departureTime": 1573,
    "delay": "-1.0",
    "line": "8",
    "stationName": "rndmname",
    "direction": 2
  }],
"station157": [{
    "departureTime": 1842,
    "delay": "-2.0",
    "line": "8",
    "stationName": "randomname",
    "direction": 2
  }]
}}
Community
  • 1
  • 1
hfbr
  • 11
  • 3
  • What you have tried so far with the help of answer you mentioned. – Garry Jul 21 '15 at 10:18
  • 1
    You should add your code here, so that we can help you. – Sujay Jul 21 '15 at 10:20
  • I added some code, thank you. – hfbr Jul 21 '15 at 10:30
  • 1
    but response is not a type of `ServerResponse` but `HashMap>` ... there is no filed `stationsInResponse` in json – Selvin Jul 21 '15 at 11:33
  • so i need to give my Map the same name as something in my JSON file? the problem is, all the stations in my JSON file are called different, like "station96", "station 120" and so on. – hfbr Jul 21 '15 at 16:19
  • instead of retreiving a ServerResponse, use `new TypeToken>>() { }.getType()` as type, and retrieve it as a `Map>`. – njzk2 Jul 21 '15 at 16:58

2 Answers2

1

Here is the working code:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.google.gson.Gson;

public class GSONTest {

    public static void main(String[] args){

        String gsonStr = "{\"stationsInResponse\": { \"station62\":[  {  \"departureTime\":1982,\"delay\":\"-1.0\",\"line\":\"6\",\"stationName\":\"randomname\",\"direction\":2} ],\"station63\":[  {  \"departureTime\":1981,\"delay\":\"-1.1\",\"line\":\"7\",\"stationName\":\"randomname2\",\"direction\":3} ]}}";

        Gson gson = new Gson();
        Response response = gson.fromJson(gsonStr, Response.class);

        System.out.println("Map size:"+response.getStationsInResponse().size());

        for (Iterator iterator = response.getStationsInResponse().keySet().iterator(); iterator.hasNext();) {

            String key = (String) iterator.next();

            ArrayList<Station> stationList = (ArrayList<Station>) response.getStationsInResponse().get(key);

            for (Iterator iterator2 = stationList.iterator(); iterator2.hasNext();) {

                Station station = (Station) iterator2.next();

                System.out.println("Delay: "+station.getDelay());
                System.out.println("DepartureTime: "+station.getDepartureTime());
                System.out.println("Line: "+station.getLine());
                System.out.println("StationName: "+station.getStationName());
            }


        }


    }


}

class Response {
      private Map<String, List<Station>> stationsInResponse;
      //getters and setters

    public Map<String, List<Station>> getStationsInResponse() {
        return stationsInResponse;
    }

    public void setStationsInResponse(Map<String, List<Station>> stationsInResponse) {
        this.stationsInResponse = stationsInResponse;
    }
    }

class Station {
      private String departureTime;
      public String getDepartureTime() {
        return departureTime;
    }
    public void setDepartureTime(String departureTime) {
        this.departureTime = departureTime;
    }
    public String getDelay() {
        return delay;
    }
    public void setDelay(String delay) {
        this.delay = delay;
    }
    public String getLine() {
        return line;
    }
    public void setLine(String line) {
        this.line = line;
    }
    public String getStationName() {
        return stationName;
    }
    public void setStationName(String stationName) {
        this.stationName = stationName;
    }
    public String getDirection() {
        return direction;
    }
    public void setDirection(String direction) {
        this.direction = direction;
    }
      private String delay;
      private String line;
      private String stationName;
      private String direction;

}

Output in console is like this(as I shortened your json string):

Map size:2
Delay: -1.0
DepartureTime: 1982
Line: 6
StationName: randomname
Delay: -1.1
DepartureTime: 1981
Line: 7
StationName: randomname2
Garry
  • 4,493
  • 3
  • 28
  • 48
  • yes, that is what is mentioned over there: http://stackoverflow.com/questions/16377754/parse-json-file-using-gson/16378782#16378782 i have tried that exact way, but the Map stays empty. – hfbr Jul 21 '15 at 16:55
  • not that either. each value of the map is a list, not a station. – njzk2 Jul 21 '15 at 16:57
  • @hfbr ...updated the code for second json where stationsInResponse is used. – Garry Jul 21 '15 at 20:01
  • thanks for the updated answer. looks like it is the same approach as @Nicklas answer. I do not get my JSON like in the edit of my original post, but i thought it would be the way i needed it. i will see if the people that provide me the JSON can put the structure that way. – hfbr Jul 22 '15 at 07:43
  • @hfbr yes, this is as per the json provided in edit2 – Garry Jul 22 '15 at 08:52
  • thanks again. would there still be a way to parse the original JSON i provided at the top of my first post? – hfbr Jul 22 '15 at 17:50
  • I tried but different stations like station62 and station63 is causing some problem. – Garry Jul 22 '15 at 17:57
0

First I'll point out your mistake, then I'll give you the solution.

The structure you're asking for in your deserialization code looks like this:

{
    "stationsInResponse": {
        "station1": [
            {
                "name": "Station 1"
            }
        ],
        "station2": [
            {
                "name": "Station 2"
            }
        ]
    }
}

Solution

The deserialization code you really need to deserialize the structure you're getting as input, is as follows:

Gson gson = new Gson();
Type rootType = new TypeToken<Map<String, List<Station>>>(){}.getType();
Map<String, List<Station>> stationsMap = gson.fromJson(json, rootType);

This is because a JSON object, whose properties are unknown at compile-time, which your root object is, maps to a Java Map<String, ?>. The ? represent the expected Java type of the JSON object value, which in your case is either List<Station> or Station[], whichever you prefer.

If you wanted to, you could combine all the stations in the map into one List of stations like so:

List<Station> stations = new ArrayList<>(stationsMap.size());
for (List<Station> stationsList : stationsMap.values()) {
    for (Station station : stationsList) {
        stations.add(station);
    }
}
Nicklas Jensen
  • 1,424
  • 12
  • 19
  • Thanks for this answer. the problem is, that in my original JSON (see the original JSON in my first post), the "stationsInResponse" is not there. The JSON starts right away with certain station objects. Whether this is correct or not i can't judge, but this is the way the JSON was provided to me so far. Anyway, i think your solution will work if i make my JSON look like the one used in your answer. One more question: If i removed all the [ and ] from the JSON, then the structure needed to deserialize would just be Map stationsMap , is that correct? – hfbr Jul 22 '15 at 07:39
  • oh and one more question. would the first JSON (top of my original post) i posted be parsable too? since your answer is referring to the second JSON, and so far it seems that the people that generate that JSON can only provide the structure of the first one. – hfbr Jul 22 '15 at 17:52