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

2 Answers 2

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.

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

5 Comments

Thx for the tip! Going to check it out as I speak.
I managed to achieve what I wanted by using ArrayNode array = json.withArray("fieldName"); Thank you very much sebster!
@sebster you made my day. Works perfectly
Instead of new ObjectMapper(), you could also go with Json.mapper() to get Play's global mapper.
@JulianV.Modesto: You're right. I'll add it to the answer.
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.

3 Comments

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."
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 :) )
@OriLentz : Dont you mean ArrayNode arr = (ArrayNode)node; ?

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.