How to access default serializer when writing custom serialiser

2,069 views
Skip to first unread message

Tim Dudgeon

unread,
Jun 23, 2015, 10:18:36 AM6/23/15
to jackso...@googlegroups.com
Hi,

I'm writing a custom serialiizer, extending StdSerializer.
In the 
public void serialize(MoleculeObject mo, JsonGenerator jg, SerializerProvider sp)
method I need to be able to access the default json serialization mechanism, but I don't see how to do this.
I can't call super.serialize() as its abstract, and using JsonGenerator.writeObject() or SerializerProvider.defaultSerializeValue() end up calling my custom serialize() method and end up with stack overflow.

How should I be doing this?

Tim

Tatu Saloranta

unread,
Jun 23, 2015, 11:20:14 AM6/23/15
to jackso...@googlegroups.com
The main method for doing this is bit indirect: you need to register BeanSerializerModifier, and in method `modifySerializer(...)` you are handed the default serializer. You can then construct your own serializer, retaining reference to the default, and use it as appropriate.

Other methods will not work since they would simply find serializer you have registered.

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

Tim Dudgeon

unread,
Jun 23, 2015, 12:39:27 PM6/23/15
to jackso...@googlegroups.com
So to be sure I've understood this

1. create my own BeanSerializerModifier  and implement this method:

public JsonSerializer<?> modifySerializer(SerializationConfig config,
                                 BeanDescription beanDesc,
                                 JsonSerializer<?> serializer)

Then in that method somehow (using beanDesc.getBeanClass() ?)  find out of its the serializer for my class, if so return my custom JsonSerializer keeping a reference to the default one, if not return the default one.
And if I needed to do this for a lot of different classes I'd end up with a big  if ... else statement.

2. specify that BeanSerializerModifier using SimpleModule.setSerializerModifier( ... )

Thanks
Tim

Tatu Saloranta

unread,
Jun 23, 2015, 1:23:58 PM6/23/15
to jackso...@googlegroups.com
Yes, exactly.

-+ Tatu +-

Zsolt Balanyi

unread,
Mar 20, 2017, 11:49:41 AM3/20/17
to jackson-user
Hi All!

But what can I do when I want to use annotation, and I don't have access to the mapper?
Eg:

@JsonSerialize(using = ASerializer.class)
public class AClass {
...
}


BR, Zsolt

Tatu Saloranta

unread,
Mar 20, 2017, 2:21:29 PM3/20/17
to jackson-user
Not 100% sure I understand the question, but if you want to access
information about annotations on property, from your custom
serializer, you need to implement `ContextualSerializer`, and then its
`createContextual()` gets called with `BeanProperty`.
`BeanProperty` has accessors for annotation directly; or, you can then
call `AnnotationIntrospector` (accessible from `SerializerProvider`
that is also passed).

-+ Tatu +-

Zsolt Balanyi

unread,
Mar 20, 2017, 2:58:33 PM3/20/17
to jackson-user
Hi!

What I meant is that I would like to get (or create ) the default Jackson Serializer for the object being serialized, and store as default.
Then I could implement serialize as follows:

@Override
public void serialize(Object o, JsonGenerator jg, SerializerProvider sp) throws IOException {
  doMyStuff...
  default.serialize(o, jg, sp);
}

The challenge here is that only a no-arg constructor is called for the serializer if the serializer is used in annotation like this: @JsonSerialize(using = UIElementSerializer.class)

BR, Zsolt

Tatu Saloranta

unread,
Mar 20, 2017, 3:13:25 PM3/20/17
to jackson-user
This can not be done from annotation-based serializer: it will
override default logic.
The only way to access what would otherwise be created/used as the
standard serializer is to register `BeanSerializerModifier`, and
override handling of `modifySerializer`.

-+ Tatu +-

Zsolt Balanyi

unread,
Mar 20, 2017, 4:08:26 PM3/20/17
to jackson-user
Hi!

OK, thanks, then I'll go that way!

BR, Zsolt

Tatu Saloranta

unread,
Mar 20, 2017, 4:24:27 PM3/20/17
to jackson-user
Good luck! That approach is used quite a lot so it should work fine.
Note, too, that it may be combined with ContextualSerializer if you do
need to access annotations.
In fact you can use `createContextual()` sometimes to simply decide if
override is needed at all; if not, return default serializer from that
method and you are good to go (but if so, remember to delegate call).

It would be great to find better ways to allow such "partial"
overrides, in a more convenient way.
But until then, Bean(De)SerializerModifier is the way to go.

-+ Tatu +-

Zsolt Balanyi

unread,
Mar 21, 2017, 3:25:51 AM3/21/17
to jackson-user
Hi!

This is exactly what I was wondering... if there is a way to automate the default serializer injection, when the custom serializer gets detected.
I am also willing to contribute to the code, if I am provided some guidance.

BR, Zsolt

Zsolt Balanyi

unread,
Mar 21, 2017, 4:16:17 AM3/21/17
to jackson-user
This article points out exactly the fact, that the usage of BeanSerializerModifier makes in unnecessary to use the annotation!
So I would happily contribute to make the @JsonSerialize smarter. :)

BR, Zsolt

Zsolt Balanyi

unread,
Mar 21, 2017, 4:16:46 AM3/21/17
to jackson-user
Reply all
Reply to author
Forward
0 new messages