6

My JSON string has nested values.

Something like

"[{"listed_count":1720,"status":{"retweet_count":78}}]"

I want the value of the retweet_count.

I'm using Jackson.

The code below outputs "{retweet_count=78}" and not 78. I'm wondering if I can get nested values the kind of way PHP does it i.e status->retweet_count. Thanks.

import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;

public class tests {
public static void main(String [] args) throws IOException{
    ObjectMapper mapper = new ObjectMapper();
  List <Map<String, Object>> fwers = mapper.readValue("[{\"listed_count\":1720,\"status\":{\"retweet_count\":78}}]]", new TypeReference<List <Map<String, Object>>>() {});
    System.out.println(fwers.get(0).get("status"));

    }
}
Mob
  • 10,958
  • 6
  • 41
  • 58
  • That is to be expected: va;ue of 'status' is a Map isn't it? You just need to call 'get()' one more time with "retweet_count". However, I agree with one of the responses that suggests use of `readTree()` instead, to get a `JsonNode` -- much easier to traverse. – StaxMan Dec 06 '11 at 19:10

3 Answers3

13

If you know the basic structure of the data you're retrieving, it makes sense to represent it properly. You get all sorts of niceties like type safety ;)

public static class TweetThingy {
    public int listed_count;
    public Status status;

    public static class Status {
        public int retweet_count;
    }
}

List<TweetThingy> tt = mapper.readValue(..., new TypeReference<List<TweetThingy>>() {});
System.out.println(tt.get(0).status.retweet_count);
ptomli
  • 11,730
  • 4
  • 40
  • 68
9

Try something like that. If you use JsonNode your life gonna be easier.

JsonNode node = mapper.readValue("[{\"listed_count\":1720,\"status\":{\"retweet_count\":78}}]]", JsonNode.class);

System.out.println(node.findValues("retweet_count").get(0).asInt());
Jaroslaw.zawila
  • 509
  • 2
  • 4
  • 14
2

You can probably do System.out.println(fwers.get(0).get("status").get("retweet_count"));

Edit 1:

Change

List <Map<String, Object>> fwers = mapper.readValue(..., new TypeReference<List <Map<String, Object>>>() {});

to

List<Map<String, Map<String, Object>>> fwers = mapper.readValue(..., new TypeReference<List<Map<String, Map<String, Object>>>>() {});

And then do System.out.println(fwers.get(0).get("status").get("retweet_count"));

You don't have a Map of pairs, you have a Map of <String, Map<String, Object>> pairs.

Edit 2:

Alright I get it. So you have a list of maps. And in the first map in the list, you have a kv pair where the value is an integer, and another kv pair where the value is another map. When you say you have a list of maps of maps it complains because the kv pair with the int value isn't a map (it's just an int). So you either have to make all of your kv pairs maps (change that int to a map) and then use my edits above. Or you can use your original code, but cast the Object to a Map when you know it is a Map.

So try this:

Map m = (Map) fwers.get(0).get("status");
System.out.println(m.get("retweet_count"));
Andrew Rasmussen
  • 14,912
  • 10
  • 45
  • 81
  • I've tried this it doesn't work. The get("status") is a normal object – Mob Dec 05 '11 at 16:45
  • More errors bro, : `Can not deserialize instance of java.util.LinkedHashMap out of VALUE_NUMBER_INT token` – Mob Dec 05 '11 at 17:00