Is it possible do serialize/deserialize multilevel json objects?

2.3k views Asked by At

When I have a simple json it is easy, take

{"type":"simple","content":"i love apples"}

I just create a pojo:

public class Example {
    public Object type;
    public Object content;
}

Then doing:

ObjectMapper mapper = new ObjectMapper();
Example ex = mapper.readValue(getInputStream(),Example.class)

will do the job.

But now suppose I have something more complicated, a multilevel json

{
    "type": "complicated",
    "params": [
        {
            "type": "simple",
            "content": "i still love apples"
        },
        {
            "type": "simple", 
            "content":"i love spam too"
        }
    ]
}

As you can see the "params" field of this new Object is a json array, and each element of this array could be mapped to my Example pojo class.

Is there a way to do this? Sorry if it could seem trivial, but I can't find any good documentation about jackson... it just talks about simple cases.

4

There are 4 answers

3
fge On BEST ANSWER

Here you go!

NOTE: no setters in the class, which is why I have to use @JsonCreator. Habit of mine, I don't do beans ;)

If you have setters for the different fields you can do without @JsonCreator at all.

public final class Jackson
{
    private static final String JSONCONTENT
        = "{" +
            "\"type\":\"complicated\"," +
            "\"params\":[" +
            "{\"type\":\"simple\"," + "\"content\":\"i still love apples\"}," +
            "{\"type\":\"simple\",\"content\":\"i love spam too\"}" +
            "]" +
        "}";
    public static void main(final String... args)
        throws IOException
    {
        final ObjectMapper mapper = new ObjectMapper();
        final Complicated complicated
            = mapper.readValue(JSONCONTENT, Complicated.class);
        System.out.println("Deserialization done");
        System.out.println("Serializing");
        System.out.println(mapper.writeValueAsString(complicated));
    }
}

class Complicated
{
    private final String type;
    private final List<Simple> params;

    @JsonCreator
    Complicated(@JsonProperty("type") final String type,
        @JsonProperty("params") final List<Simple> params)
    {
        this.type = type;
        this.params = new ArrayList<Simple>(params);
    }

    public String getType()
    {
        return type;
    }

    public List<Simple> getParams()
    {
        return Collections.unmodifiableList(params);
    }
}

class Simple
{
    private final String type;
    private final String content;

    @JsonCreator
    Simple(@JsonProperty("type") final String type,
        @JsonProperty("content") final String content)
    {
        this.type = type;
        this.content = content;
    }

    public String getType()
    {
        return type;
    }

    public String getContent()
    {
        return content;
    }
}
0
Zarathustra On

Yes it is possible, I don't know how it is with Jackson but in many JSON libraries it works when you have a List of Objects in your Example class.

0
mig8 On

it's possible. Here is an example with flexjson:

  1. I have a list of groups, in that every groups has a list of users
  2. The relevant code sequence:

    try (
            ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream( baos );
            FileOutputStream fos = new FileOutputStream( outputFileName ); )
    {
        oos.writeObject( groupList );
        fos.write( baos.toByteArray() );
    }
    
6
Krish Srinivasan On

For your case you can use google gson : https://code.google.com/p/google-gson/

Using that library the following simple code produces the output you want :

@Test
public void testGson() {
    Gson gson = new Gson();
    Param param = new Param("simple", "i still love apples");
    Enclosure enclosure = new Enclosure("complex", param);
    String json = gson.toJson(enclosure);
    System.out.println(json);
}
output : {"type":"complex","param":{"type":"simple","content":"i still love apples"}}

You can also do more complex serializations using Gson so it should fit your needs as you expand in serialization.