Search code examples
javajsonjacksondeserializationjson-deserialization

How to parse raw values from JSON array items with Jackson?


Using Jackson deserialization it would be great to have an option
to deserialize JSON array of items (of any nature: object, number, string) to a Java array of String.

I see that @JsonRawValue allows to have similar functionality for nested fields.
Is it possible to implement the same for "top level" objects?

void test(){
    var payload = """ [
          {"a": 1, "b": "hello"},
          {"a": 2, "b": "bye"},
          "something"
    ]
    """;

    // What else is required to get the effect of @JsonRawValue ?

    String[] rawItems = new ObjectMapper().readValue(payload, String[].class);

    assertEquals("""{"a": 1, "b": "hello"}""", rawItems[0]);
    assertEquals("""{"a": 2, "b": "bye"}""", rawItems[1]);
    assertEquals("\"something\"", rawItems[2]);
}

Solution

  • You can convert the payload to com.fasterxml.jackson.databind.node.ArrayNode and then iterate through elements (JsonNode in this case) and add them to a List<String> (which you can then convert to String[] if you want).

    One thing to be aware of - the formatting will not be as you expect. JsonNode has two methods - toString() which deletes all the white space and toPrettyString which adds whitespaces and newlines to the final String

            String payload = """ 
            [
              {"a": 1, "b": "hello"},
              {"a": 2, "b": "bye"},
              "something"
            ]
            """;
            ArrayNode items = new ObjectMapper().readValue(payload, ArrayNode.class);
    
            List<String> rawItemsList = new ArrayList<>();
    
            for (JsonNode jsonNode : items) {
                rawItemsList.add(jsonNode.toString());
            }
    
            // You can just keep using the rawItemsList, but I've converted it to array since the question mentioned it
            String[] rawItemsArr = rawItemsList.toArray(new String[0]);
    
            assertEquals("""
                    {"a":1,"b":"hello"}""", rawItemsArr[0]);
            assertEquals("""
                    {"a":2,"b":"bye"}""", rawItemsArr[1]);
            assertEquals("\"something\"", rawItemsArr[2]);