gwt-jackson
gwt-jackson copied to clipboard
Support for JacksonJsonSerializer and JacksonJsonDeserializer (@JsonSerialize and @JsonDeserialize) without special gwtjackson variants
We have a dozen Score classes in OptaPlanner (= widely open source Constraint Solver in java), which are used by my users, both in their backend and their frontend. For example, HardSoftScore implements Score.
We maintain a set of Jackson serializers and deserializers, which are used like this, for example:
@JsonSerialize(using = ScoreJacksonJsonSerializer.class)
@JsonDeserialize(using = HardSoftScoreJacksonJsonDeserializer.class)
private HardSoftScore score = null;
Gwtjackson doesn't pick up those 2 annotations (@JsonSerialize and @JsonDeserialize) and maintaining a set of Gwtjackson JsonSerializer and JsonDeserializer is a big pain for me. Gwtjackson should be able to reuse my Jackson JsonSerializer and JsonDeserializers. It is still allowed to crash GWT compilation if those custom (de)serializers use non-GWT allowed Java code (such as reflection).
How can we make that happen? Let's take a look at 2 of my implementations, I don't see any dangerous code in there for GWT:
public class ScoreJacksonJsonSerializer<Score_ extends Score<Score_>>
extends JsonSerializer<Score_> {
@Override
public void serialize(Score_ score, JsonGenerator generator, SerializerProvider serializers) throws IOException {
generator.writeString(score.toString());
}
}
public class HardSoftScoreJacksonJsonDeserializer extends AbstractScoreJacksonJsonDeserializer<HardSoftScore> {
@Override
public HardSoftScore deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return HardSoftScore.parseScore(parser.getValueAsString());
}
}
Would it be possible to mock that JsonGenerator, SerializerProvider, JsonParser and DeserializationContext with super sources?
I made some updates to at least support the using parameter of those annotations. But for now, the entire serializer/deserializer has to be super sourced.
To reuse the jackson (de)serializer, it requires super source of all the jackson class as you said and mapping between
JsonParser<>JsonReader,JsonGenerator<>JsonWriterDeserializationContext<>JsonDeserializationContext+JsonDeserializerParametersSerializerProvider<>JsonSerializationContext+JsonSerializerParameters.
I don't know how you can convert JsonReader to JsonParser though. The compiler would probably be ok if you add JsonReader with a setter on your super sourced JsonParser but probably not the IDE since the signature would be different and it has no knowledge of the super source.
Maybe with an interface implemented by the super sourced JsonParser, a replace-with rule and a call to GWT.create.
Once it's done, it should be possible to make a custom gwt-jackson JsonSerialize and JsonDeserialize that instantiate the jackson one and call the (de)serialize method.
I won't have time for such work but feel free to try!
You should not need modification in gwt-jackson source code for that. Just register a custom gwt-jackson serializer for your Score class and try to call your jackson serializer inside it.