8

I have the following Json structure:

{
    "name": "John",
    "surname": "Doe",
    "languages": [
    {"language": "english", "level": "3"},
    {"language": "french", "level": "1"}
    ]
}

I am using the Play Framework to parse Json data from a HTTP message, which was sent by using an self-developed REST service. I know already how I can parse the name and surname from the Json data by looking at the documentation, this is done by:

JsonNode json = request().body().asJson();
String name = json.findPath("name").textValue();
String surname = json.findPath("surname").textValue();

Now my question is, how I can parse the array "languages" in the Json data. I have found some other posts about this problem, but they were all using Scala, which I cant get my head around, so preferably I'm looking for a Java solution.

I have already tried several things, like for example this:

    List<JsonNode> languages = json.findPath("languages").getElements();

According to the documentation json.findPath() returns a JsonNode, on which can be called the function getElements(), which would return an Iterator of JsonNode. But I get a compile error on getElements: "The method getElements() is undefined for the type JsonNode"

Anyone knows of an easy way to parse such an array? Thanks in advance

sebster
  • 1,322
  • 2
  • 18
  • 29
jbrulmans
  • 975
  • 1
  • 11
  • 32

2 Answers2

14

You could do it in a for-each loop like this:

JsonNode json = request().body().asJson();

for (JsonNode language : json.withArray("languages")) {
    Logger.info("language -> " + language.get("someField").asText());
    //do something else
}

Or, if you're into lambdas:

json.withArray("languages").forEach(language -> Logger.info("language -> " + language));

Also... the correct way to create an ArrayNode:

//using a mapper(important subject the mapper is)
ObjectMapper mapper = new ObjectMapper();
ArrayNode array = mapper.createArrayNode();

//using an existing ArrayNode from a JsonNode
ArrayNode array = json.withArray("fieldName");

//or using Play's Json helper class
ArrayNode array = Json.newArray();

You should really read more about the capabilities of jackson/fasterxml. It's a very performant lib. A good start is JacksonInFiveMinutes.

sebster
  • 1,322
  • 2
  • 18
  • 29
1

Try this:

JsonNode node = (JsonNode)json.findPath("languages");
ArrayNode arr = (ArrayNode)node;
Iterator<JsonNode> it = arr.iterator();
while (it.hasNext()) {
    JSONObject obj = it.next();
    System.out.println("language: " + obj.findPath("language").getTextValue();
}

Here I'm simply printing one of the elements, but you could do whatever you want of course :)

Hope this helps.

Ori Lentz
  • 3,668
  • 6
  • 22
  • 28
  • The constructor of JSONArray does not seem to accept an object of type 'JsonNode' unfortunately. _"JSONException: JSONArray initial value should be a string or collection or array."_ – jbrulmans May 04 '15 at 13:42
  • Really? That's a bit odd. I've edited my answer to try and give another option. I don't think I have any other way in mind if that doesn't work. Is there a reason why you're using Play Framework specifically or can you maybe try a different parse? If so, I recommend Gson or something like that, it's much more Java-friendly (and is a lot more documented with Java examples :) ) – Ori Lentz May 04 '15 at 13:58
  • @OriLentz : Dont you mean `ArrayNode arr = (ArrayNode)node;` ? – ccheneson May 04 '15 at 14:17