Register custom TypeIdResolver on ObjectMapper without using JsonTypeIdResolver annotation

1,224 views
Skip to first unread message

Paolo Bazzi

unread,
Nov 29, 2016, 8:40:42 AM11/29/16
to jackson-user
Hi,

I have a question regarding a custom TypeIdResolver. Is there a possibility to register a custom TypeIdResolver class or instance on the used ObjectMapper instance, without having to annotate the serialized beans with @JsonTypeIdResolver annotation?

Background information: We use the serialized beans as interface between multiple systems and do not wan't to have a dependency to jackson-databind on the maven module providing the interface beans. Instead we would prefer to have the dependendy to jackson-databind only within the code, which actually performs the serialization/deserialization.


A rather hacky workaround would be to intercept the AnnotationIntrospector as follow. But a programmatic way to register the custom TypeIdResolver would be preferred.


    ObjectMapper mapper = new ObjectMapper();

    mapper = mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
      private static final long serialVersionUID = 1L;

      @SuppressWarnings("unchecked")
      @Override
      protected <A extends Annotation> A _findAnnotation(Annotated annotated, Class<A> annoClass) {
        A annotation = super._findAnnotation(annotated, annoClass);
        if (JsonTypeIdResolver.class.equals(annoClass) && annotation == null) {
          return (A) new JsonTypeIdResolver() {
            @Override
            public Class<? extends Annotation> annotationType() {
              return JsonTypeIdResolver.class;
            }

            @Override
            public Class<? extends TypeIdResolver> value() {
              return CustomTypeNameIdResolver.class;
            }
          };
        }
        return annotation;
      }
    });


Regards,
Paolo

Tatu Saloranta

unread,
Nov 29, 2016, 2:33:40 PM11/29/16
to jackso...@googlegroups.com
Unfortunately handling of TypeIdResolver is quite strongly coupled
with that of `TypeResolverBuilder`, and your best route would probably
be via annotation introspector. Although I actually like your approach
above: did not know it would actually work (I spent some time back in
the day trying to figure out if implementing annotation types via
non-annotation declaration works... didn't think it did).

Anyway, method to override would be

public TypeResolverBuilder<?> findTypeResolver(MapperConfig<?> config,
AnnotatedClass ac, JavaType baseType) { }

and you should be able to just use base implementation, but call
`init(...)` on builder instance if one found, to override default
resolver.

This is not optimal of course.

One more existing facility is method

public ObjectMapper setDefaultTyping(TypeResolverBuilder<?> typer) { ... }

in ObjectMapper. This does let you control all type id aspects,
including type id resolution, but is quite a bit of work.

-+ 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.
Reply all
Reply to author
Forward
0 new messages