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.

Reply via email to