Extending JacksonAnnotationIntrospector to Identify Attributes for Serialization

679 views
Skip to first unread message

Dave Ariens

unread,
Jul 29, 2015, 2:39:39 PM7/29/15
to jackson-user
Originally posted on the issue list.

I was having a hard time getting a JacksonAnnotationIntrospector extended class to identify which attributes to include for serialization.  I want Jackson to only serialize an object's item (property, field, method) if a specific annotation exists.  Since posting to the issue list I resolved my earlier problem (I was using Lombok to auto-generate Getters/Setters) and now have the Introspector working.

The only issue remaining is that I must annotate the field, and getter (if exists) and setter (if exists) for the field to be serialized.  

This requirement exists regardless of what the mapper's default visibility is for fields, getters, isGetters, etc.

I would expect that if I'm using an extended JacksonAnnotationIntrospector that overrides hasIgnoreMarker and checks the annotated member for a specific annotation and return true if present, false if not that which ever property/field/method is annotated will get serialized, and there wouldn't be any relationship between field/getter/setter.




Tatu Saloranta

unread,
Jul 29, 2015, 3:19:54 PM7/29/15
to jackso...@googlegroups.com
I am not sure whether this is the cause, but note that both @JsonIgnore and @JsonProperty are associative, meaning that if only one accessors is annotated with only of them, it affects all accessor.

That is: if you indicate that getter has @JsonIgnore, it will lead to ignorable of the whole property, unless some other accessors (setter, field) has @JsonProperty (in which case individual accessors are treated differently).

If getter has @JsonProperty, then all accessors are included, unless overridden by @JsonIgnore.

Visibility level only affects implicit inclusion in absence of annotations.

In your case it sounds like you would not want to indicate 'hasIgnoreMarker()', but instead override `findNameForSerialization()` and `findNameForDeserialization()`. These are methods that look for @JsonProperty.

-+ 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.

Dave Ariens

unread,
Jul 29, 2015, 5:49:51 PM7/29/15
to jackson-user, tsalo...@gmail.com
Can you elaborate more on how I can override findNameForSerialization() to have only fields/methods/etc with a specific annotation present serialized?

I extended it and logged what it was checking (all my object's attributes and methods) and then called super.findNameForSerialization() and logged/returned the returned value.  It appears as though it's the value is always null.  

This is expected because I don't use @JsonProperty.

It would seem to me that I would want to continue to override hasIgnoreMarker() and but then also annotate the attribute/field/method with @JsonProperty.  I tested this and it works however I would really like to not have to use the @JsonProperty annotation in addition my custom annotation.  

Tatu Saloranta

unread,
Jul 29, 2015, 7:23:36 PM7/29/15
to Dave Ariens, jackson-user
Since you only care about serialization, I would override "findNameForSerialization()", and implement it so that:

1. If you do not see annotation you want in member passed, return `null`
2. If you do see annotation, return `super.findNameForSerialization()`

Or, if you also want to allow use of `@JsonProperty`, modify (1) to check what super-class method returns.

However: going back to what you are trying to achieve -- do you simply want to avoid using Jackson annotations directly? If so, have you considered instead using meta-annotation @JacksonAnnotationsInside? Adding that in your own annotation allows you to construct "annotation bundles", explained briefly at:

http://www.cowtowncoder.com/blog/archives/2012/03/entry_466.html
(section 2.6)
with example annotation of:

  @Retention(RetentionPolicy.RUNTIME)
  @JacksonAnnotationsInside
  @JsonInclude(Include.NON_NULL) // only include non-null properties
  @JsonPropertyOrder({ "id", "name" }) // ensure that 'id' and 'name' are always serialized before other properties
  public @interface StdAnnotations
but same also works for property annotations, not just class annotations.  

-+ Tatu +-



Dave Ariens

unread,
Jul 29, 2015, 7:48:12 PM7/29/15
to Tatu Saloranta, jackson-user
I'll check that out, in the meantime do you know if it's possible to gain access to the instantiated class that owns the annotated member from within "findNameForSerializatiion()"?   ‎The object I'm using will inherit an array of access levels set on it that I am hoping to compare against a string array of defined permission levels within the annotation I'm looking for and then I will either serialize or de-serialize if the annotated member matches the access level set on the object.

Ideally I would have hoped this filtering could have been possible out of the box with Jackson but it's not (to my knowledge).    

It would be awesome to use @JsonProperty(access_levels={"role1", "role2"}) and then be able to set target access level on the mapper, with a default.   

If I can't gain access to the instantiated object within the "findNameForSerialization()" annotated member reference then I might have to use a custom serializer but iterating over complex nested object structure calling Jason generator methods accordingly is massive overkill.  

Sent from my BlackBerry 10 smartphone on the TELUS network.
From: Tatu Saloranta
Sent: Wednesday, July 29, 2015 7:23 PM
To: Dave Ariens
Cc: jackson-user
Subject: Re: [jackson-user] Extending JacksonAnnotationIntrospector to Identify Attributes for Serialization

Tatu Saloranta

unread,
Jul 29, 2015, 8:11:23 PM7/29/15
to jackson-user
No, the idea is that AnnotationIntrospector only checks for annotations on member, and it should not try to do any more work than that. I probably do not fully understand your use case at this point.

As to serialization, there are many other options; if you have not yet checked out @JsonView or @JsonFilter, I would recommend doing so:

http://www.cowtowncoder.com/blog/archives/2011/02/entry_443.html

-+ Tatu +-


Reply all
Reply to author
Forward
0 new messages