Skip to content

Commit a066415

Browse files
committed
Fix #2236
1 parent 90479d3 commit a066415

File tree

4 files changed

+46
-4
lines changed

4 files changed

+46
-4
lines changed

release-notes/VERSION-2.x

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ Project: jackson-databind
3333
(reported by RightHandedMonkey@github)
3434
#2230: `WRITE_BIGDECIMAL_AS_PLAIN` is ignored if `@JsonFormat` is used
3535
(reported by Pavel C)
36+
#2236: Type id not provided on `Double.NaN`, `Infinity` with `@JsonTypeInfo`
37+
(reported by C-B-B@github)
3638
#2241: Add `JsonPropertyNamingStrategy.LOWER_DOT_CASE` for dot-delimited names
3739
(contributed by zenglian@github.com)
3840

src/main/java/com/fasterxml/jackson/databind/ser/std/NumberSerializers.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import com.fasterxml.jackson.annotation.JsonFormat;
88

99
import com.fasterxml.jackson.core.*;
10-
10+
import com.fasterxml.jackson.core.type.WritableTypeId;
1111
import com.fasterxml.jackson.databind.*;
1212
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
1313
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
@@ -220,11 +220,27 @@ public void serialize(Object value, JsonGenerator gen,
220220

221221
// IMPORTANT: copied from `NonTypedScalarSerializerBase`
222222
@Override
223-
public void serializeWithType(Object value, JsonGenerator gen,
223+
public void serializeWithType(Object value, JsonGenerator g,
224224
SerializerProvider provider, TypeSerializer typeSer)
225225
throws IOException {
226226
// no type info, just regular serialization
227-
serialize(value, gen, provider);
227+
// 08-Feb-2018, tatu: Except that as per [databind#2236], NaN values need
228+
// special handling
229+
Double d = (Double) value;
230+
if (notFinite(d)) {
231+
WritableTypeId typeIdDef = typeSer.writeTypePrefix(g,
232+
// whether to indicate it's number or string is arbitrary; important it is scalar
233+
typeSer.typeId(value, JsonToken.VALUE_NUMBER_FLOAT));
234+
g.writeNumber(d);
235+
typeSer.writeTypeSuffix(g, typeIdDef);
236+
} else {
237+
g.writeNumber(d);
238+
}
239+
}
240+
241+
public static boolean notFinite(double value) {
242+
// `jackson-core` has helper method in 3 but not yet
243+
return Double.isNaN(value) || Double.isInfinite(value);
228244
}
229245
}
230246
}

src/test/java/com/fasterxml/jackson/databind/BaseMapTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ public StringWrapper(String value) {
7777

7878
protected static class ObjectWrapper {
7979
final Object object;
80-
protected ObjectWrapper(final Object object) {
80+
81+
public ObjectWrapper(final Object object) {
8182
this.object = object;
8283
}
8384
public Object getObject() { return object; }

src/test/java/com/fasterxml/jackson/databind/jsontype/deftyping/TestDefaultForScalars.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,18 @@ static class Data {
2323
public long key;
2424
}
2525

26+
// Basic `ObjectWrapper` from base uses delegating ctor, won't work well; should
27+
// figure out why, but until then we'll use separate impl
28+
protected static class ObjectWrapperForPoly {
29+
Object object;
30+
31+
protected ObjectWrapperForPoly() { }
32+
public ObjectWrapperForPoly(final Object o) {
33+
object = o;
34+
}
35+
public Object getObject() { return object; }
36+
}
37+
2638
/*
2739
/**********************************************************************
2840
/* Test methods
@@ -128,4 +140,15 @@ public void testDefaultTypingWithLong() throws Exception
128140
assertNotNull(result);
129141
assertEquals(2, result.size());
130142
}
143+
144+
// [databind#2236]: do need type info for NaN
145+
public void testDefaultTypingWithNaN() throws Exception
146+
{
147+
final ObjectWrapperForPoly INPUT = new ObjectWrapperForPoly(Double.POSITIVE_INFINITY);
148+
final String json = DEFAULT_TYPING_MAPPER.writeValueAsString(INPUT);
149+
final ObjectWrapperForPoly result = DEFAULT_TYPING_MAPPER.readValue(json, ObjectWrapperForPoly.class);
150+
assertEquals(Double.class, result.getObject().getClass());
151+
assertEquals(INPUT.getObject().toString(), result.getObject().toString());
152+
assertTrue(((Double) result.getObject()).isInfinite());
153+
}
131154
}

0 commit comments

Comments
 (0)