tom91136
tom91136

Reputation: 8962

Jackson JSON force deserialize to object

I got a class setup with delegation

public class MyClass implements List<Integer> {

    public String name;

    public List<Integer> target; // this is the delegation target
    // more fields

    @Override
    public Integer get(int index) {
        return target.get(index);
    }
    // all other method in target interface is delegated 
}

And I got a JSON that looks like this:

{"target": [1, 2, 3] , "name":"foo"}

And Jackson throws this:

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.foo.MyClass out of START_OBJECT token
 at [Source: java.io.StringReader@156e5f3e; line: 1, column: 1]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
    at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:691)
    at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:685)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.handleNonArray(CollectionDeserializer.java:256)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:214)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:204)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:23)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2986)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2091)

I was speculating that Jackson thought MyClass is a list so didn't know what to do with {} because [] is expected

I confirmed my speculation by making MyClass not implement List<Integer> :

public class MyClass { /*same stuff*/}

And everything worked. But I need MyClass to implement List<Integer>....

Is there an annotation or configuration in module that I can use to solve this?

Upvotes: 4

Views: 1538

Answers (2)

tom91136
tom91136

Reputation: 8962

I stumbled upon my answer while reading this article, Basically, I need to annotate my class with

@JsonFormat(shape = Shape.OBJECT)

Upvotes: 2

Andrew E
Andrew E

Reputation: 8327

You can probably write a custom deserializer but I really think the problem will be much better solved if you remove the List inheritance.

What is the requirement to implement that interface? Wouldn't it make more sense for your top level class to have an accessor to the list instead of implementing an interface? From an OO perspective, your top level class is not a "kind of" list. Remove the inheritance and you have a cleaner design that works with Jackson.

Upvotes: 1

Related Questions