Many thanks for your response Tatu - looking forward to a fix.
A couple more questions on the approach for the workaround:
- I've implemented the below CustomDoubleSerializer - how bad do you
think the performance impact would be for our Double serialisations, at a
high level, between "barely noticeable" and "very bad"?
- Isn't there a way I can get this to only apply for Map element
serialisations?
- Or even better, create a custom MapSerializer that would behave just
like the defaut MapSerializer, except when it comes to serializing Doubles?
If so what's the easiest way to do so? I'm getting a little lost when
trying to do that!
Many thanks,
CBB
PS : apologies for the dark code background, not sure how best to include
code snippets
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.std.NumberSerializers;
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
import java.io.IOException;
public class CustomDoubleSerializer extends JsonSerializer<Double> {
private NumberSerializers.DoubleSerializer doubleSerializer;
private StdScalarSerializer<Double> scalarSerializer;
public CustomDoubleSerializer() {
this.doubleSerializer = new
NumberSerializers.DoubleSerializer(Double.class);
this.scalarSerializer = new StdScalarSerializer<Double>(Double.class) {
@Override
public void serialize(Double aDouble, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
doubleSerializer.serialize(aDouble, jsonGenerator,
serializerProvider);
}
};
}
@Override
public void serialize(Double aDouble, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
doubleSerializer.serialize(aDouble, jsonGenerator, serializerProvider);
}
@Override
public void serializeWithType(Double aDouble, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider, TypeSerializer typeSerializer) throws
IOException {
if (aDouble != null && (aDouble.isInfinite() || aDouble.isNaN())) {
scalarSerializer.serializeWithType(aDouble, jsonGenerator,
serializerProvider, typeSerializer);
} else {
doubleSerializer.serialize(aDouble, jsonGenerator,
serializerProvider);
}
}
}
On Sunday, 27 January 2019 07:22:07 UTC, Tatu Saloranta wrote:
>
> On Sat, Jan 26, 2019 at 7:08 PM C-B-B <[email protected] <javascript:>>
> wrote:
> >
> > Hello folks,
> >
> > I've been trying to serialise and deserialise a Map<String, Object>
> whilst preserving the type of the elements, for example a Long should
> remain a Long and not become an Integer.
> > This works pretty well using the @JsonTypeInfo annotation on the Map.
> Jackson is being clever, and only including the type info when it is needed
> (e.g. it won't include it on an Integer, String, Double etc as they are
> default deserialisation types anyway), which is nice.
> > There's however a nasty edge case with Double.NaN,
> Double.POSITIVE_INFINITY and Double.NEGATIVE_INFINITY: they get serialised
> without type info, and get deserialised as Strings...
> >
> > I've raised this as an issue, but in the meantime I'm looking for a
> workaround to include the type info on these Doubles (I've checked, and the
> deserialisation of NaN and infinity values works fine if the type is
> included).
> > Ideally, the customised code would only be invoked for that Map object,
> rather that for all serialisations (I've been able to override the
> DoubleSerializer altogether on the ObjectMapper, but would rather not make
> such an invasive change).
>
> I agree that this is a bug, and hope to eventually resolve it as per
> issue filed.
>
> But in the meantime I do think that custom deserializer is the way to
> go; and there's no easy way to change to only occur for Map values
> (delegation model means that same DoubleDeserializer is used for
> properties and map values).
>
> -+ Tatu +-
>
> >
> > I've tried a few things, including with TypeIdResolver, but no luck so
> far... Any help would be much appreciated!
> >
> > Here's a little repro
> >
> > import com.fasterxml.jackson.annotation.JsonTypeInfo;
> > import com.fasterxml.jackson.databind.ObjectMapper;
> > import java.io.IOException;
> > import java.util.HashMap;
> > import java.util.Map;
> >
> > public class Repro {
> > private static ObjectMapper objectMapper = new ObjectMapper();
> >
> > public static void main(String[] args) {
> > try {
> > String beanString = objectMapper.writeValueAsString(new
> Bean(1L, Double.NaN));
> > MapHolder beanOut = objectMapper.readValue(beanString,
> MapHolder.class);
> > System.out.println(beanOut.data.get("double").getClass());
> > beanString = objectMapper.writeValueAsString(new Bean(1L,
> 1D));
> > beanOut = objectMapper.readValue(beanString,
> MapHolder.class);
> > System.out.println(beanOut.data.get("double").getClass());
> > } catch (IOException e) {
> > e.printStackTrace();
> > }
> > }
> >
> > public static class Bean {
> > private Long longValue;
> > private Double doubleValue;
> >
> > public Bean(Long longValue, Double doubleValue) {
> > this.longValue = longValue;
> > this.doubleValue = doubleValue;
> > }
> >
> > @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include =
> JsonTypeInfo.As.PROPERTY, property = "@class")
> > public Map<String, Object> getData() {
> > Map<String, Object> map = new HashMap<>();
> > map.put("long", longValue);
> > map.put("double", doubleValue);
> > return map;
> > }
> > }
> >
> > public static class MapHolder {
> > public Map<String, Object> data;
> > MapHolder() {}
> > }
> > }
> >
> >
> >
> > --
> > 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 [email protected] <javascript:>.
> > To post to this group, send email to [email protected]
> <javascript:>.
> > For more options, visit https://groups.google.com/d/optout.
>
--
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 [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/d/optout.