diff --git a/play-json/jvm/src/main/scala/play/api/libs/json/jackson/JacksonJson.scala b/play-json/jvm/src/main/scala/play/api/libs/json/jackson/JacksonJson.scala index 44f0c090d..a02226ac1 100644 --- a/play-json/jvm/src/main/scala/play/api/libs/json/jackson/JacksonJson.scala +++ b/play-json/jvm/src/main/scala/play/api/libs/json/jackson/JacksonJson.scala @@ -67,12 +67,8 @@ sealed class PlayJsonMapperModule(jsonConfig: JsonConfig) extends SimpleModule(" // -- Serializers. private[jackson] class JsValueSerializer(jsonConfig: JsonConfig) extends JsonSerializer[JsValue] { - import java.math.BigInteger import java.math.{ BigDecimal => JBigDec } - import com.fasterxml.jackson.databind.node.BigIntegerNode - import com.fasterxml.jackson.databind.node.DecimalNode - private def stripTrailingZeros(bigDec: JBigDec): JBigDec = { val stripped = bigDec.stripTrailingZeros if (jsonConfig.bigDecimalSerializerConfig.preserveZeroDecimal && bigDec.scale > 0 && stripped.scale <= 0) { @@ -96,10 +92,7 @@ private[jackson] class JsValueSerializer(jsonConfig: JsonConfig) extends JsonSer val stripped = stripTrailingZeros(v.bigDecimal) val raw = if (shouldWritePlain) stripped.toPlainString else stripped.toString - if (raw.indexOf('E') < 0 && raw.indexOf('.') < 0) - json.writeTree(new BigIntegerNode(new BigInteger(raw))) - else - json.writeTree(new DecimalNode(new JBigDec(raw))) + json.writeTree(new StringBasedNumericNode(raw)) } case JsString(v) => json.writeString(v) diff --git a/play-json/jvm/src/main/scala/play/api/libs/json/jackson/StringBasedNumericNode.scala b/play-json/jvm/src/main/scala/play/api/libs/json/jackson/StringBasedNumericNode.scala new file mode 100644 index 000000000..042b307a3 --- /dev/null +++ b/play-json/jvm/src/main/scala/play/api/libs/json/jackson/StringBasedNumericNode.scala @@ -0,0 +1,44 @@ +/* + * Copyright (C) from 2022 The Play Framework Contributors , 2011-2021 Lightbend Inc. + */ + +package play.api.libs.json.jackson + +import com.fasterxml.jackson.core.{ JsonGenerator, JsonParser, JsonToken } +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.node.NumericNode + +import java.math.{ BigDecimal, BigInteger } + +/** + * A numeric node that is represented as a string. + * + * For internal use only. Some methods are not implemented and will throw an exception. + */ +private[jackson] case class StringBasedNumericNode(text: String) extends NumericNode { + + override def numberType = JsonParser.NumberType.BIG_DECIMAL + + override def asText(): String = text + + override def asToken(): JsonToken = JsonToken.VALUE_NUMBER_FLOAT + + override def serialize(jgen: JsonGenerator, ctxt: SerializerProvider): Unit = + jgen.writeNumber(text) + + override def numberValue: Number = throw new NotImplementedError + + override def intValue: Int = throw new NotImplementedError + + override def longValue: Long = throw new NotImplementedError + + override def doubleValue: Double = throw new NotImplementedError + + override def decimalValue: BigDecimal = throw new NotImplementedError + + override def bigIntegerValue: BigInteger = throw new NotImplementedError + + override def canConvertToInt: Boolean = false + + override def canConvertToLong: Boolean = false +}