J'ai un Range
que j'ai besoin de sérialiser dans un certain format, à savoir "[lower,upper)"
. Pour ce faire, je l'ai écrit un sérialiseur de base:Sérialiser Range avec Jackson
public class RangeSerializer extends StdSerializer<Range<?>> {
@Override
public void serialize(final Range<?> value, final JsonGenerator gen, final SerializerProvider provider) throws IOException {
if (value != null) {
gen.writeRaw('"');
gen.writeRaw('[');
provider.defaultSerializeValue(value.lowerEndpoint(), gen);
gen.writeRaw(',');
provider.defaultSerializeValue(value.upperEndpoint(), gen);
gen.writeRaw(')');
gen.writeRaw('"');
}
}
(Notez que, en réalité, la sérialisation gère les différentes possibilités de Range
telles que les plages fermées/ouvertes, la possibilité de plages sans bornes à l'une des extrémités, etc., mais pour les fins de ma question qui ne sont pas pertinentes, donc je l'ai supprimé pour garder le code simple). Mon problème est qu'en revenant au sérialiseur par défaut pour chaque classe je me retrouve avec des citations au mauvais endroit. Par exemple, si j'avais un Range<String>
avec une entrée "[foo,bar)"
puis lors de la sérialisation, j'obtiens "["foo","bar")"
. J'ai besoin du résultat sans guillemets autour des valeurs de point final inférieur et supérieur.
Je comprends que les citations supplémentaires sont parce que gen.writeString()
dans le sérialiseur sous-jacent ne réalise pas qu'il est déjà dans une chaîne. Y a-t-il un moyen de le faire savoir au générateur ou un autre moyen de réaliser ce que je tente de faire?
Notez que Range<?>
est vraiment générique, donc je ne peux pas coder en dur la sérialisation des valeurs. Il doit fonctionner pour Range<Integer>
, Range<String>
, Range<DateTime>
et toute autre chose.
Merci pour la réponse. Un convertisseur est une façon intéressante de faire les choses, mais peut-il être enregistré de la même manière que les sérialiseurs et les désérialiseurs peuvent être enregistrés ou doit-il être attaché avec une annotation? Je n'ai pas accès à la classe Range elle-même, et la plage est en fait utilisée comme clé pour une carte, donc je ne suis pas sûr qu'une solution basée sur des annotations puisse m'aider ici. – jgm
Utilisez un mixage pour ajouter l'annotation à la classe Range. J'ai édité ma réponse pour montrer comment. Notez la partie 'addMixin (...)' configurée sur le mappeur. –