Search code examples
javajsonserializationjacksonjson-serialization

How to parse a Java List of already parsed JSON into a Big JSON?


I use Jackson to serialize/deserialize JSON.

I have a List<String> in which all elements inside are already serialized in JSON format. I would like to generate a big JSON from that List.

In other word, I have:

List<String> a = new ArrayList<>();
a[0] = JSON_0
a[1] = JSON_1
...
a[N] = JSON_N

And I would like to render:

[
   {JSON_0},
   {JSON_1},
   ...
   {JSON_N}
]

What is the best way to do so using Jackson?


Solution

  • Probably the simpler solution would be to create ArrayNode and use addRawValue method:

    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.node.ArrayNode;
    import com.fasterxml.jackson.databind.util.RawValue;
    
    public class JsonApp {
    
        public static void main(String[] args) throws Exception {
            ObjectMapper mapper = new ObjectMapper();
    
            ArrayNode nodes = mapper.getNodeFactory().arrayNode();
            nodes.addRawValue(new RawValue("{}"));
            nodes.addRawValue(new RawValue("true"));
            nodes.addRawValue(new RawValue("{\"id\":1}"));
    
            System.out.println(mapper.writeValueAsString(nodes));
        }
    }
    

    Above code prints:

    [{},true,{"id":1}]
    

    You can also, create a POJO with list and use @JsonRawValue annotation. But if you can not have extra root object you need to implement custom serialiser for it. Example with POJO and custom serialiser:

    import com.fasterxml.jackson.core.JsonGenerator;
    import com.fasterxml.jackson.databind.JsonSerializer;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.SerializerProvider;
    import com.fasterxml.jackson.databind.annotation.JsonSerialize;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    public class JsonApp {
    
        public static void main(String[] args) throws Exception {
            ObjectMapper mapper = new ObjectMapper();
    
            List<String> jsons = new ArrayList<>();
            jsons.add("{}");
            jsons.add("true");
            jsons.add("{\"id\":1}");
    
            RawJsons root = new RawJsons();
            root.setJsons(jsons);
            System.out.println(mapper.writeValueAsString(root));
        }
    }
    
    @JsonSerialize(using = RawJsonSerializer.class)
    class RawJsons {
    
        private List<String> jsons;
    
        public List<String> getJsons() {
            return jsons;
        }
    
        public void setJsons(List<String> jsons) {
            this.jsons = jsons;
        }
    }
    
    class RawJsonSerializer extends JsonSerializer<RawJsons> {
    
        @Override
        public void serialize(RawJsons value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
            gen.writeStartArray();
            if (value != null && value.getJsons() != null) {
                for (String json : value.getJsons()) {
                    gen.writeRawValue(json);
                }
            }
            gen.writeEndArray();
        }
    }
    

    If you need to have SerializationFeature.INDENT_OUTPUT feature enabled for all items in array, you need to deserialise all inner objects and serialise them again.

    See also: