Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polymorphic Jackson deserialization: getting either a string or an array of strings

Tags:

java

json

jackson

My question is pretty much identical to this one, except that I'm using Java/Jackson instead of C#:

In C# how can I deserialize this json when one field might be a string or an array of strings?

My input JSON can be this:

{ "foo": "a string" }

or this:

{ "foo": ["array", "of", "strings" ] }

My class looks like this:

class MyClass {
    public List<String> foo;
}

If the input contains a single string, I want it to become the first entry in the list.

How can I deserialize foo using Jackson? I could write a custom deserializer, which I've done before, but I thought there might be an easier way.

like image 654
ccleve Avatar asked Mar 03 '15 21:03

ccleve


People also ask

Is it possible to deserialize a JSON string?

In contrast to the serialization case, there is no simple way to perform deserialization (simple or polymorphic) on a JSON string. The deserializer cannot infer the appropriate type for an object from the string. But how can then the custom converter infer the correct polymorphic type from the JSON object?

How does JUnit serialization / deserialization work?

A Truck instance is mapped to the named type Truck for example, And It runs a JUnit which checks the serialization / deserialization produces exactly the same object. If we take a look at the produced Json, it looks like the following: Jackson has added a @type attribute to each vehicle json.

What is polymorphism in Java?

That’s why I’ve decided to make this little tutorial to help you get the idea quickly with practical code examples. Polymorphism is the ability to have different implementations represented by a single interface or abstract class.

Why doesn’t This JSON string contain the properties of derived classes?

As result, we get a JSON string that does not contain the properties defined in the derived classes: We can see that the method serializes only the properties of the base class. This behavior prevents potentially sensitive data from derived classes from being serialized by accident.


1 Answers

There is a feature called ACCEPT_SINGLE_VALUE_AS_ARRAY which is turned off by default but you can turn it on:

objectMapper = new ObjectMapper()
        .configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

You can also turn it on per usage:

class SomeClass {

  @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
  private List<String> items;
  // ...
}
like image 95
Alireza Mirian Avatar answered Nov 05 '22 11:11

Alireza Mirian