On Fri, Apr 28, 2017 at 5:42 AM, Johan L <
johan....@gmail.com> wrote:
> Thank you for your answers!
>
> We've deliberately avoided mix-ins, so far, mostly because the legacy system
> (that we're adding rest/json on top of) is quite large, so it would result
> in quite a lot of mixins needed. And I completely agree with you that using
> full class names is not an optimal solution (but we're still doing a poc, so
> its ok for now). If we switch over to
JsonTypeInfo.Id.NAME later on, how
> would you add that (I'm guessing that we need to implement some kind of
> translator between class and name), if we don't go with mixins or
> annotations?
Type id <-> class name translation is configurable; piece that does it
is `TypeIdResolver`, constructed by
`TypeResolverBuilder`. One way to "inject" builder would be overriding
public TypeResolverBuilder<?> findTypeResolver(MapperConfig<?> config,
of AnnotationIntrospector (like JacksonAnnotationIntrospector). Note,
too, that despite name this class does not need to be based on
annotations at all -- it is simply the abstraction to decouple actual
annotations (jackson, jaxb, custom) from configuration actions.
> We're in full control of the JSON that is sent in. But we choose to send the
> interface name (com.acme.zoo.Dog) in the json, because there might be
> different concrete implementations (depending on customer adaptations, hence
> the factories). But if that conflicts with PM then we have to go with
> concrete classes until we add id<->class translations.
If you use type name over class you can send interfaces; this is not
fundamentally problematic.
Although you could consider possibly using simpler ids than interface
classes as well.
But that's your choice.
> Preferably we would only have to add @class to the cases where jackson
> cannot figure it out based on the target. I.e only for cases where we have
> fields with interfaces, lists with generics or sub classes.
The main limitation really is that determination of whether type is
needed has to be static (based on target class hierarchy),
and not dynamic just based on JSON content. There are issues/wishes to
implement basic type discovery, based on (for example)
presence/absence of a property, but no implementation yet. It may be
something to implement in future, but does not exist yet.
With that limit, Jackson does indeed only require (and look for) type
id in cases it considers it necessary.
> Right now I'm toying around with the previous code example and
> enableDefaultTyping(ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT,
> As.PROPERTY), Then serialize it with writeValueAsString and see if I can
> de-serialize it with readValue. It seems that if animals in Zoo is defined
> as List<?> jackson adds @class and can de-serialize it. But if its
> List<Animal> then it doesn't add @class, nor can it de-serialize (even if I
> manually add @class to the json). How come? :)
At root value level -- and only there -- type is taken from instance,
and subject to Java Type Erasure.
This means that all generic types, like ArrayList<> etc, will only be
seen as `ArrayList<?>`: parameterization is only available to
compiler. But anything reachable via properties DOES retain
parameters.
My recommendation is to never use generic types as root values: always
POJO (or array).
But if they are used then full type needs to be passed
(ObjectMapper.writerFor(type).....).
This is typically not a problem for deserialization since type must be
passed anyway so callers usually pass full generic type.
It's only for serialization where convenience of passing instance
lures callers into false sense of safety :)
-+ 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 post to this group, send email to
jackso...@googlegroups.com.
> For more options, visit
https://groups.google.com/d/optout.