Skip to content

Commit b30fa09

Browse files
committed
Fix #1911
1 parent cb24c3b commit b30fa09

File tree

3 files changed

+56
-2
lines changed

3 files changed

+56
-2
lines changed

release-notes/VERSION-2.x

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ Project: jackson-databind
44
=== Releases ===
55
------------------------------------------------------------------------
66

7+
2.9.5 (not released yet)
8+
9+
#1911: Allow serialization of `BigDecimal` as String, using
10+
`@JsonFormat(shape=Shape.String)`, config overrides
11+
(suggested by cen1@github)
12+
713
2.9.4 (24-Jan-2018)
814

915
#1382: `@JsonProperty(access=READ_ONLY)` unxepected behaviour with `Collections`

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
import java.math.BigDecimal;
66
import java.math.BigInteger;
77

8+
import com.fasterxml.jackson.annotation.JsonFormat;
89
import com.fasterxml.jackson.core.JsonGenerator;
910
import com.fasterxml.jackson.core.JsonParser;
1011
import com.fasterxml.jackson.databind.*;
1112
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
1213
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
14+
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
1315

1416
/**
1517
* As a fallback, we may need to use this serializer for other
@@ -20,6 +22,7 @@
2022
@SuppressWarnings("serial")
2123
public class NumberSerializer
2224
extends StdScalarSerializer<Number>
25+
implements ContextualSerializer
2326
{
2427
/**
2528
* Static instance that is only to be used for {@link java.lang.Number}.
@@ -37,6 +40,21 @@ public NumberSerializer(Class<? extends Number> rawType) {
3740
_isInt = (rawType == BigInteger.class);
3841
}
3942

43+
@Override
44+
public JsonSerializer<?> createContextual(SerializerProvider prov,
45+
BeanProperty property) throws JsonMappingException
46+
{
47+
JsonFormat.Value format = findFormatOverrides(prov, property, handledType());
48+
if (format != null) {
49+
switch (format.getShape()) {
50+
case STRING:
51+
return ToStringSerializer.instance;
52+
default:
53+
}
54+
}
55+
return this;
56+
}
57+
4058
@Override
4159
public void serialize(Number value, JsonGenerator g, SerializerProvider provider) throws IOException
4260
{

src/test/java/com/fasterxml/jackson/databind/ser/jdk/NumberSerTest.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,19 @@ public class NumberSerTest extends BaseMapTest
1919

2020
static class IntWrapper {
2121
public int i;
22-
2322
public IntWrapper(int value) { i = value; }
2423
}
25-
24+
25+
static class DoubleWrapper {
26+
public double value;
27+
public DoubleWrapper(double v) { value = v; }
28+
}
29+
30+
static class BigDecimalWrapper {
31+
public BigDecimal value;
32+
public BigDecimalWrapper(BigDecimal v) { value = v; }
33+
}
34+
2635
static class IntAsString {
2736
@JsonFormat(shape=JsonFormat.Shape.STRING)
2837
@JsonProperty("value")
@@ -39,6 +48,16 @@ static class DoubleAsString {
3948
public double value = -0.5;
4049
}
4150

51+
static class BigIntegerAsString {
52+
@JsonFormat(shape=JsonFormat.Shape.STRING)
53+
public BigInteger value = BigInteger.valueOf(123456L);
54+
}
55+
56+
static class BigDecimalAsString {
57+
@JsonFormat(shape=JsonFormat.Shape.STRING)
58+
public BigDecimal value = BigDecimal.valueOf(0.25);
59+
}
60+
4261
static class NumberWrapper {
4362
// ensure it will use `Number` as statically force type, when looking for serializer
4463
@JsonSerialize(as=Number.class)
@@ -87,15 +106,26 @@ public void testNumbersAsString() throws Exception
87106
assertEquals(aposToQuotes("{'value':'3'}"), MAPPER.writeValueAsString(new IntAsString()));
88107
assertEquals(aposToQuotes("{'value':'4'}"), MAPPER.writeValueAsString(new LongAsString()));
89108
assertEquals(aposToQuotes("{'value':'-0.5'}"), MAPPER.writeValueAsString(new DoubleAsString()));
109+
assertEquals(aposToQuotes("{'value':'0.25'}"), MAPPER.writeValueAsString(new BigDecimalAsString()));
110+
assertEquals(aposToQuotes("{'value':'123456'}"), MAPPER.writeValueAsString(new BigIntegerAsString()));
90111
}
91112

92113
public void testConfigOverridesForNumbers() throws Exception
93114
{
94115
ObjectMapper mapper = new ObjectMapper();
95116
mapper.configOverride(Integer.TYPE) // for `int`
96117
.setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING));
118+
mapper.configOverride(Double.TYPE) // for `double`
119+
.setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING));
120+
mapper.configOverride(BigDecimal.class)
121+
.setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING));
122+
97123
assertEquals(aposToQuotes("{'i':'3'}"),
98124
mapper.writeValueAsString(new IntWrapper(3)));
125+
assertEquals(aposToQuotes("{'value':'0.75'}"),
126+
mapper.writeValueAsString(new DoubleWrapper(0.75)));
127+
assertEquals(aposToQuotes("{'value':'-0.5'}"),
128+
mapper.writeValueAsString(new BigDecimalWrapper(BigDecimal.valueOf(-0.5))));
99129
}
100130

101131
public void testNumberType() throws Exception

0 commit comments

Comments
 (0)