I am using a third-party POJO class RetryOptions
that can only be created using a builder. The builder can only be instantiated using a static method RetryOptions.newBuilder()
, or by calling options.toBuilder()
on an existing instance.
I would like to create custom de/serializers for the third-party POJO (RetryOptions
). My first approach was to write the object as a builder, then read the object as a builder and return the built result:
class RetryOptionsSerializer extends StdSerializer<RetryOptions> {
@Override
public void serialize(RetryOptions value, JsonGenerator gen, SerializerProvider provider) throws IOException {
// Save as a builder
gen.writeObject(value.toBuilder());
}
}
class RetryOptionsDeserializer extends StdDeserializer<RetryOptions> {
@Override
public RetryOptions deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
// Read as builder, then build
return p.readValueAs(RetryOptions.Builder.class).build();
}
}
But the problem is that Jackson doesn't know how to create an instance of RetryOptions.Builder
in order to populate it's fields.
Is there a way I can instruct Jackson in how to create the builder instance, but let Jackson handle the parsing, reflection, and assignment of the fields?
Perhaps something like:
class RetryOptionsDeserializer extends StdDeserializer<RetryOptions> {
@Override
public RetryOptions deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
// Read as builder, then build
var builder = RetryOptions.newBuilder();
return p.readValueInto(builder).build();
}
}
Or perhaps there is a way to tell the object mapper how to create an instance of RetryOptions.Builder
:
var mapper = new ObjectMapper();
mapper.registerValueInstantiator(RetryOptions.Builder, () -> RetryOptions.newBuilder());
Or is there another way to slice this problem without resorting to my own reflection logic or a brute-force duplication of the third-party class?
Note: my solution must use the Jackson JSON library (no Guava, etc.)
Note: there are several classes in this third party library that run into this same issue, so a generic solution is helpful