Question

I have a JSON Structure looking like this:

[
    {
        "id": 0,
        "name": "Foo"
    },
    {
        "id": 1,
        "name": "Bar"
    }
]

and a corresponding Java Object for Data binding:

public class Thing {
    public int id;
    public String name;
}

I know how I could deserialize the JSON list into a list of Thing.

Now here comes the tricky part: What I want to do is deserializing the JSON into a class looking like the following snippet by only doing changes to this class:

public class Things {
    private List<Thing> things;

    public void setThings(List<Thing> things) {
        this.things = things;
    }

    public List<Thing> getThings() {
        return this.things;
    }
}

This is because the JSON deserialization is build in deep in our application by using an ObjectMapper like this:

private static <T> T parseJson(Object source, Class<T> t) {

    TypeReference<T> ref = new TypeReference<T>() {
    };
    TypeFactory tf = TypeFactory.defaultInstance();

    //[...]

    obj = mapper.readValue((String) source, tf.constructType(ref));

    //[...]

    return obj;
}

Are there any annotations with which I can achieve what I want or do I have to make changes to the mapper-code?

Much thanks in advance, McFarlane

Was it helpful?

Solution

The whole point of TypeReference, as described in this link, is to use the generic type argument to retrieve type information.

Internally it does the following

Type superClass = getClass().getGenericSuperclass();
...
_type = ((ParameterizedType) superClass).getActualTypeArguments()[0];

where getActualTypeArguments()[0] will give you the actual type argument. In this case, that will be the type variable T, regardless of what you pass in for the Class<T> t parameter of your method.

The proper usage is

TypeReference<List<Thing>> ref = new TypeReference<List<Thing>>() {};
...
List<Thing> thingsList = ...;
Things things = new Things();
things.setThings(thingsList);

In other words, no, you'll need to change your mapper code to achieve what you want.

As far as I know, you won't be able to map a root JSON array as a property of a class. The alternatives is the TypeReference example above or some other ones found here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top