From 5704a8027a99150689d72354c2474d6578d52208 Mon Sep 17 00:00:00 2001 From: frankwong15 Date: Fri, 3 Jan 2020 22:31:21 +0800 Subject: [PATCH] Fix guyboertje#59 Add an option to serialize BigDecimal as String --- src/main/java/com/jrjackson/JrJacksonBase.java | 3 ++- src/main/java/com/jrjackson/RubyAnySerializer.java | 13 +++++++++++-- test/jrjackson_test.rb | 10 ++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/jrjackson/JrJacksonBase.java b/src/main/java/com/jrjackson/JrJacksonBase.java index 5b1748e..7d866d9 100644 --- a/src/main/java/com/jrjackson/JrJacksonBase.java +++ b/src/main/java/com/jrjackson/JrJacksonBase.java @@ -54,6 +54,7 @@ public static IRubyObject generate(ThreadContext context, IRubyObject self, IRub jgen.useDefaultPrettyPrinter(); } + Boolean stringifyBigDecimal = flagged(options, RubyUtils.rubySymbol(_ruby, "stringify_bigdecimal")); SerializerProvider provider; if (format != null) { SimpleDateFormat simpleFormat = new SimpleDateFormat(format); @@ -67,7 +68,7 @@ public static IRubyObject generate(ThreadContext context, IRubyObject self, IRub } try { - RubyAnySerializer.instance.serialize(args[0], jgen, provider); + new RubyAnySerializer(stringifyBigDecimal).serialize(args[0], jgen, provider); jgen.close(); ByteList bl = new ByteList(baos.toByteArray(), UTF8Encoding.INSTANCE); diff --git a/src/main/java/com/jrjackson/RubyAnySerializer.java b/src/main/java/com/jrjackson/RubyAnySerializer.java index a92a296..abb34b5 100644 --- a/src/main/java/com/jrjackson/RubyAnySerializer.java +++ b/src/main/java/com/jrjackson/RubyAnySerializer.java @@ -37,9 +37,14 @@ public class RubyAnySerializer extends JsonSerializer { private static final RUBYCLASS[] CLASS_NAMES = RUBYCLASS.values(); + private final Boolean stringifyBigDecimal; + public RubyAnySerializer() { -// super(IRubyObject.class); + this(false); + } + public RubyAnySerializer(Boolean stringifyBigDecimal) { + this.stringifyBigDecimal = stringifyBigDecimal; } private void serializeUnknownRubyObject(ThreadContext ctx, IRubyObject rubyObject, JsonGenerator jgen, SerializerProvider provider) @@ -190,7 +195,11 @@ public void serialize(IRubyObject value, JsonGenerator jgen, SerializerProvider } break; case BigDecimal: - jgen.writeNumber(((RubyBigDecimal) value).getBigDecimalValue()); + if (this.stringifyBigDecimal) { + jgen.writeString(value.callMethod(value.getRuntime().getCurrentContext(), "to_s", value.getRuntime().newString("F")).toString()); + } else { + jgen.writeNumber(((RubyBigDecimal) value).getBigDecimalValue()); + } break; case Time: serializeTime((RubyTime) value, jgen, provider); diff --git a/test/jrjackson_test.rb b/test/jrjackson_test.rb index 6aa3e72..815476d 100755 --- a/test/jrjackson_test.rb +++ b/test/jrjackson_test.rb @@ -565,6 +565,16 @@ def test_concurrent_dump # ----------------------------- + def test_can_serialize_bigdecimal_as_string + object = {"foo" => BigDecimal.new('0.12345678901234567890123456789')} + + actual = JrJackson::Json.dump(object) + assert_equal "{\"foo\":0.12345678901234567890123456789}", actual + + actual = JrJackson::Json.dump(object, :stringify_bigdecimal => true) + assert_equal "{\"foo\":\"0.12345678901234567890123456789\"}", actual + end + def assert_bigdecimal_equal(expected, actual) assert_equal expected, actual assert_equal expected.class, actual.class