Derialize/deserialize to a Map<String, Object> with type for bean and no type for primitive/collection/map

50 views
Skip to first unread message

nit...@gmail.com

unread,
Jul 18, 2022, 6:02:22 AM7/18/22
to jackson-user
Hello,

I hope my question will not be another "why doesn't Jackson find polymorphic type for my Map values (or List or Set)" and  I hope I did my best to check for any question/answer :).

I have a bean with an any field: 
@JsonAnyGetter
@JsonAnySetter
protected Map<String, Object> properties = new HashMap<>();

When initializing the map with:
properties.put("foo", new FooBean());
properties.put("foos", List.of(new FooBean()));
properties.put("long", 123);
properties.put("longs", List.of(123));
properties.put("longss", List.of(List.of(123)));

I want to produce:
{
"foo": {
"@class": "org.FooBean", "foo": "bar"
},
"foos": [
{
"@class": "org.FooBean", "foo": "bar"
}
],
"long": 123,
"longs": [123, 567],
"longss": [[123], 567]
}

ie. a type for bean but not for primitive or collection/map.

Is this use case achievable by using jackson? To quote that post  if there'd be an option that says, if there is a type attribute at the beginning, create this type, rather than a natural one. 

Thanks for your help

Nicolas



Nicolas Labrot

unread,
Jul 18, 2022, 7:47:31 AM7/18/22
to jackso...@googlegroups.com
I think for the moment I will try to create a custom serializer / deserializer for my properties map
- Serializer: introspect the map and build JavaType then call the appropriate serialize 
- Deserializer: convert first into a TreeNode and then introspect the TreeNode (basically, if map and @type then try to create the associated deserializer)


--
You received this message because you are subscribed to a topic in the Google Groups "jackson-user" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jackson-user/abEAvuiMeac/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jackson-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jackson-user/f62bae35-a14e-4f9f-b152-6bfcf2e83873n%40googlegroups.com.

Tatu Saloranta

unread,
Jul 18, 2022, 1:23:17 PM7/18/22
to jackson-user
On Mon, Jul 18, 2022 at 4:47 AM Nicolas Labrot <nit...@gmail.com> wrote:
>
> I think for the moment I will try to create a custom serializer / deserializer for my properties map
> - Serializer: introspect the map and build JavaType then call the appropriate serialize
> - Deserializer: convert first into a TreeNode and then introspect the TreeNode (basically, if map and @type then try to create the associated deserializer)
>

Ok so:

1. No, I don't think there is a way to make Polymorphic handling work
with "Any" properties with `Object` as value
2. But if you just have `Map<String,Object>`, you SHOULD be able to
simply use `@JsonTypeInfo` annotation on Map property (field or
accessor)

So I would first try (2), I think.

It _might_ just work with `@JsonValue` as well, if you needed
"JsonAnySetter/Getter"-like behavior.

-+ Tatu +-
> You received this message because you are subscribed to the Google Groups "jackson-user" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to jackson-user...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/jackson-user/CAEWXQ0oD_Xb%2B9pve35uzmsTWgvfMqT%2BDzaDNSb7kHROyPpQCgw%40mail.gmail.com.

nit...@gmail.com

unread,
Jul 19, 2022, 3:44:18 PM7/19/22
to jackson-user
Thanks for your answer.

Without the any setter/getter but with JsonTypeInfo on the map field, the @class are added to every entries at the exclusion of the java types mappable into json (so Long at its @class). But List<Integer> still have its @class. 
Without the any setter/getter, without JsonTypeInfo on the map field but with JsonTypeInfo on all the pojo classes that can be inserted into the map,  the @class are only added to those entries but at the deserialization the entry having @class are not recovered but transformed into a map 

I end up writing my own serializer / deserializer :)


Tatu Saloranta

unread,
Jul 19, 2022, 4:28:36 PM7/19/22
to jackso...@googlegroups.com
On Tue, Jul 19, 2022 at 12:44 PM nit...@gmail.com <nit...@gmail.com> wrote:
>
> Thanks for your answer.
>
> Without the any setter/getter but with JsonTypeInfo on the map field, the @class are added to every entries at the exclusion of the java types mappable into json (so Long at its @class). But List<Integer> still have its @class.
> Without the any setter/getter, without JsonTypeInfo on the map field but with JsonTypeInfo on all the pojo classes that can be inserted into the map, the @class are only added to those entries but at the deserialization the entry having @class are not recovered but transformed into a map

Ok, I am sure I follow the details here, but sounds like this does not
work the way you would like it to work.

And wrt generic container types (that is, `List<X>`), no type
information is available thanks to type erasure, that is true.

> I end up writing my own serializer / deserializer :)
> https://gist.github.com/nithril/b55d6ab32db253dfe24995f87c899685

Ok, sometimes that's what you got to do. Good luck!

-+ Tatu +-
> To view this discussion on the web visit https://groups.google.com/d/msgid/jackson-user/656951e7-25c1-4446-be91-faa56fb615fdn%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages