From ea64970d3ceac5b2efdf30cfb26952323da43e16 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Wed, 18 Jun 2025 12:40:26 +0100 Subject: [PATCH 1/3] test case for serializing custom numbers with config overrides --- .../jackson/databind/ser/jdk/NumberSerTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/test/java/tools/jackson/databind/ser/jdk/NumberSerTest.java b/src/test/java/tools/jackson/databind/ser/jdk/NumberSerTest.java index 99c4715930..df25c127c7 100644 --- a/src/test/java/tools/jackson/databind/ser/jdk/NumberSerTest.java +++ b/src/test/java/tools/jackson/databind/ser/jdk/NumberSerTest.java @@ -17,6 +17,7 @@ import tools.jackson.databind.SerializationContext; import tools.jackson.databind.ValueSerializer; import tools.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.json.JsonMapper; import tools.jackson.databind.module.SimpleModule; import tools.jackson.databind.testutil.DatabindTestUtil; @@ -117,6 +118,12 @@ public void serialize(BigDecimal value, JsonGenerator gen, SerializationContext } } + static class MyBigDecimal extends BigDecimal { + public MyBigDecimal(String value) { + super(value); + } + } + /* /********************************************************** /* Test methods @@ -225,6 +232,15 @@ public void testCustomSerializationBigDecimalAsNumber() throws Exception { assertEquals(a2q("{'value':2.0}"), mapper.writeValueAsString(new BigDecimalHolder("2"))); } + @Test + public void testConfigOverrideNonJdkNumber() throws Exception { + JsonMapper mapper = jsonMapperBuilder().withConfigOverride(MyBigDecimal.class, + c -> c.setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING))) + .build(); + String value = mapper.writeValueAsString(new MyBigDecimal("123.456")); + assertEquals(a2q("'123.456'"), value); + } + // default locale is en_US static DecimalFormat createDecimalFormatForDefaultLocale(final String pattern) { return new DecimalFormat(pattern, new DecimalFormatSymbols(Locale.ENGLISH)); From 145969330a2cd9c83c32b2a44885f2b28e1a5caa Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Wed, 18 Jun 2025 13:11:25 +0100 Subject: [PATCH 2/3] speculative fix --- .../java/tools/jackson/databind/ser/BasicSerializerFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/tools/jackson/databind/ser/BasicSerializerFactory.java b/src/main/java/tools/jackson/databind/ser/BasicSerializerFactory.java index 3acda1deb7..4d43d78366 100644 --- a/src/main/java/tools/jackson/databind/ser/BasicSerializerFactory.java +++ b/src/main/java/tools/jackson/databind/ser/BasicSerializerFactory.java @@ -313,7 +313,7 @@ protected final ValueSerializer findSerializerByPrimaryType(SerializationCont if (type.isTypeOrSubTypeOf(Number.class)) { JsonFormat.Value format = _calculateEffectiveFormat(ctxt, - beanDescRef, Number.class, formatOverrides); + beanDescRef, type.getRawClass(), formatOverrides); // 21-May-2014, tatu: Couple of alternatives actually switch (format.getShape()) { From 25823ea8ca88eb5f7131cb5bee85f1b95bc4900a Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Wed, 18 Jun 2025 14:28:55 +0100 Subject: [PATCH 3/3] add test and change speculative fix --- .../jackson/databind/ser/BasicSerializerFactory.java | 2 +- .../jackson/databind/ser/BeanSerializerFactory.java | 3 +++ .../tools/jackson/databind/ser/jdk/NumberSerTest.java | 11 ++++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/tools/jackson/databind/ser/BasicSerializerFactory.java b/src/main/java/tools/jackson/databind/ser/BasicSerializerFactory.java index 4d43d78366..3acda1deb7 100644 --- a/src/main/java/tools/jackson/databind/ser/BasicSerializerFactory.java +++ b/src/main/java/tools/jackson/databind/ser/BasicSerializerFactory.java @@ -313,7 +313,7 @@ protected final ValueSerializer findSerializerByPrimaryType(SerializationCont if (type.isTypeOrSubTypeOf(Number.class)) { JsonFormat.Value format = _calculateEffectiveFormat(ctxt, - beanDescRef, type.getRawClass(), formatOverrides); + beanDescRef, Number.class, formatOverrides); // 21-May-2014, tatu: Couple of alternatives actually switch (format.getShape()) { diff --git a/src/main/java/tools/jackson/databind/ser/BeanSerializerFactory.java b/src/main/java/tools/jackson/databind/ser/BeanSerializerFactory.java index e08abd6913..b1b18a32dc 100644 --- a/src/main/java/tools/jackson/databind/ser/BeanSerializerFactory.java +++ b/src/main/java/tools/jackson/databind/ser/BeanSerializerFactory.java @@ -161,6 +161,9 @@ public ValueSerializer createSerializer(SerializationContext ctxt, JavaT beanDescRef = ctxt.lazyIntrospectBeanDescription(type); } } + if (formatOverrides == null) { + formatOverrides = _calculateEffectiveFormat(ctxt, beanDescRef, type.getRawClass(), JsonFormat.Value.empty()); + } // Slight detour: do we have a Converter to consider? Converter conv = config.findSerializationConverter(beanDescRef.getClassInfo()); if (conv != null) { // yup, need converter diff --git a/src/test/java/tools/jackson/databind/ser/jdk/NumberSerTest.java b/src/test/java/tools/jackson/databind/ser/jdk/NumberSerTest.java index df25c127c7..1d4169a1f7 100644 --- a/src/test/java/tools/jackson/databind/ser/jdk/NumberSerTest.java +++ b/src/test/java/tools/jackson/databind/ser/jdk/NumberSerTest.java @@ -232,10 +232,19 @@ public void testCustomSerializationBigDecimalAsNumber() throws Exception { assertEquals(a2q("{'value':2.0}"), mapper.writeValueAsString(new BigDecimalHolder("2"))); } + @Test + public void testConfigOverrideJdkNumber() throws Exception { + JsonMapper mapper = jsonMapperBuilder().withConfigOverride(BigDecimal.class, + c -> c.setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING))) + .build(); + String value = mapper.writeValueAsString(new BigDecimal("123.456")); + assertEquals(a2q("'123.456'"), value); + } + @Test public void testConfigOverrideNonJdkNumber() throws Exception { JsonMapper mapper = jsonMapperBuilder().withConfigOverride(MyBigDecimal.class, - c -> c.setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING))) + c -> c.setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING))) .build(); String value = mapper.writeValueAsString(new MyBigDecimal("123.456")); assertEquals(a2q("'123.456'"), value);