8

The server I am working with returns an json object which contains a list of objects, not just one.

{
"1":{"id":"1","value":"something"},
"2":{"id":"2","value":"some other thing"}
}

I want to convert this json object into an object array.

I know I can use Gson, and create a class like this:

public class Data {
    int id;
    String value;
}

and then use

Data data = new Gson().fromJson(response, Data.class);

But it's only for the objects inside the json object. I don't know how to convert json object with number as keys.

Or alternatively I need to alter the server to response to something like this?:

{["id":"1","value":"something"],["id":"2","value":"some other thing"]}

But I don't want to change to server as I have to change all the client side codes.

Kyle Xie
  • 722
  • 1
  • 8
  • 28
  • That JSON sample looks like a Map. So how about u convert it to a map and then get the values() from that map? It looks not completely right but your Json string is not right I think:) – Neron Jul 24 '13 at 05:27
  • That is *not* a "list of objects". It's an object that contains other objects that happen to be using numbers as field names - or basically a `Map` at the most base level. – Brian Roach Jul 24 '13 at 06:30

2 Answers2

1

Your JSON looks really weird. If you can't change it, you have to deserialize it to Map. Example source code could looks like this:

import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

public class GsonProgram {

    public static void main(String... args) throws Exception {
        Gson gson = new GsonBuilder().create();
        String json = "{\"1\":{\"id\":\"1\",\"value\":\"something\"},\"2\":{\"id\":\"2\",\"value\":\"some other thing\"}}";

        Type type = new TypeToken<HashMap<String, HashMap<String, String>>>() {}.getType();
        Map<String, Map<String, String>> map = gson.fromJson(json, type);
        for (Map<String, String> data : map.values()) {
            System.out.println(Data.fromMap(data));
        }
    }
}

class Data {

    private int id;
    private String value;

    public int getId() {
        return id;
    }

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

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Data [id=" + id + ", value=" + value + "]";
    }

    public static Data fromMap(Map<String, String> properties) {
        Data data = new Data();
        data.setId(new Integer(properties.get("id")));
        data.setValue(properties.get("value"));

        return data;
    }
}

Above program prints:

Data [id=2, value=some other thing]
Data [id=1, value=something]
Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
  • Thanks, but my json object is way more complex which requires to construct a corresponding class. But I've found out a raw way to read json object which only picks up the fields I need. Thanks anyway. – Kyle Xie Jul 31 '13 at 02:27
  • @SandeepanNath, I do not understand your question. Does not accepted answer work for you? Have you tried to use `JsonParser` and `JsonElement` classes? – Michał Ziober May 24 '18 at 20:45
  • I mean how to read the first value `1` - { This one -> "1" :{"id":"1","value":"something"}, "2": {"id":"2","value":"some other thing"} } – Sandeepan Nath May 24 '18 at 20:47
  • In my example I use `Map`: `Map> map = gson.fromJson(json, type);`. You will find `1` in key set of that map. Something like `map.keySet()` – Michał Ziober May 24 '18 at 22:31
1

Because this json object uses int as the field key that you cannot specify the field key name when deserialize it. Thus I need to extract the value set from the set first:

JsonParser parser = new JsonParser();
JsonObject obj = parser.parse(json).getAsJsonObject();
Set<Entry<String,JsonElement>> set = obj.entrySet();

Now "set" contains a set of , in my case is <1,{id:1,value:something}>.

Because the key is useless here, I only need the value set, so I iterate the set to extract the value set.

for (Entry<String,JsonElement> j : set) {
            JsonObject value = (JsonObject) j.getValue();
            System.out.println(value.get("id"));
            System.out.println(value.get("value"));
        }

If you have more complex structure, like nested json objects, you can have something like this:

for (Entry<String,JsonElement> j : locations) {
            JsonObject location = (JsonObject) j.getValue();
            JsonObject coordinate = (JsonObject) location.get("coordinates");
            JsonObject address = (JsonObject) location.get("address");
            System.out.println(location.get("location_id"));
            System.out.println(location.get("store_name"));
            System.out.println(coordinate.get("latitude"));
            System.out.println(coordinate.get("longitude"));
            System.out.println(address.get("street_number"));
            System.out.println(address.get("street_name"));
            System.out.println(address.get("suburb"));
        }

Hope it helps.

Kyle Xie
  • 722
  • 1
  • 8
  • 28