On Wednesday, April 17, 2019 at 8:59:03 PM UTC-4, Tatu Saloranta wrote:
>
> On Wed, Apr 17, 2019 at 9:02 AM Chris C <[email protected] <javascript:>>
> wrote:
> >
> > On Tuesday, April 16, 2019 at 5:05:14 PM UTC-4, Tatu Saloranta wrote:
> >>
> >> On Tue, Apr 16, 2019 at 1:05 PM Chris C <[email protected]> wrote:
> >>>
> >>> I have a map of type
> >>>
> >>> Map<Key1, Map<Key2, Integer>>
> >>>
> >>> that I want to serialize to json to store in as a field in a database
> record.
> >>>
> >>> Key1 and Key2 are my own classes with getters defined and the
> constructors annotated as JsonCreators.
> >>>
> >>> I have been able to process single level maps for the same purpose by
> configuring the type factory for the object mapper, but I am unsure how to
> go about it for nested maps with different keys.
> >>
> >>
> >> There are 2 challenges:
> >>
> >> 1. Expressing `JavaType` to use for deserialization (serialization is
> usually fine, although if you try to serialize Map as root value [Strongly
> Discouraged practice!], then there too)
> >
> > Can you explain what you mean please?
>
> Which part?
>
>
Why is serializing a map as root value is discouraged? Can you give an
example of what you mean please?
>> 2. Allowing custom Map key types -- may need to register Key
> deserializers, key serializers (common types like `String`, `Number`
> supported out of the box)
> >> - note: Map keys must be scalar types; read from String, written
> as Strings
> >>
> >> First one is done using `TypeFactory`, either with TypeReference:
> >>
> >> JavaType mapRef = typeFactory.constructType(new
> TypeReference<Map<Key1, Map<Key2, Integer>>>) {} ())
> >>
> >> Or constructing it in two parts, something like
> >>
> >> JavaType mapRef = typeFactory.constructMapType(Map.class,
> typeFactory.constructType(Key1.class),
> >> typeFactory.constructMapType(Map.class,
> typeFactory.constructType(Key2.class),
> typeFactory.constructType(Integer.class)));
> >>
> >> Second part may be more involved, but if you have already handled
> non-nested maps with custom types, you probably know how that works.
> >>
> >
> > I didn't even think to chain the type factory calls here. Before I
> tackle the deserialization I ran into serialization.
> >
> > Expanding on the structure I have the following (was using
> https://www.baeldung.com/jackson-map as a starting point)
> >
> > public class Basket {
> > // other fields
> >
> >
> > // this is what I am trying to de/serialize separately
> > private Map<Seller,Map<BasketItem,Integer>> contents;
> >
> >
> > // other stuff removed
> >
> >
> >
> > @JsonSerialize(using = Seller.Serializer.class)
>
> This is only "value" serialization: values of this type as POJO
> property values. But it is not
> But it is NOT used when serializing Map keys. This because Map keys
> (and POJO property names, that is, name part of JSON objects).
>
> There is actually `keyUsing` equivalent, but that is only for `Map`
> types to indicate how keys of that Map-valued property are to be
> serialized.
>
> To associate serializer to use for Map keys of specific type you need
> to register key serializer using Modules: `SimpleModule` has method
> `addKeySerializer()` (as well as `addKeyDeserializer()`). You need to
> use these.
>
>
Got it, thanks. Added the key serializers and encapsulated the map in
another class (due to synchronized functionality) and serializing that
class directly works like a charm.
Chris
--
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 [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/d/optout.