Trying to deserialize a String to BigDecimal with a different format. The standard format, e.g. "1,000.20" works. However, in my csv the decimal delimiter and group separator are the other way round. So "1.000,20" would be the number one thousand with 20 as the two decimal places.
data class Record(
@field:JsonProperty("Amount")
val amount: BigDecimal,
)
The mapper is created with
val csvMapper = CsvMapper().apply {
registerModule(KotlinModule.Builder().build())
registerModule(JavaTimeModule())
enable(CsvParser.Feature.TRIM_SPACES)
enable(CsvParser.Feature.SKIP_EMPTY_LINES)
}
The file is read with
InputStreamReader(file.inputStream).use { reader ->
csvMapper.readerFor(Record::class.java)
.with(CsvSchema.emptySchema().withHeader().withColumnSeparator(';'))
.readValues<Record>(reader)
.readAll()
.toList();
Exception:
com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.math.BigDecimal` from String "-1,23": not a valid representation
at [Source: (InputStreamReader); line: 2, column: 53] (through reference chain: org.abc.Record["Amount"])
How can the format be specified?
Just found a question on stackoverflow including the solution to my question. The following works for me
class BigDecimalCustomDeserializer : JsonDeserializer<BigDecimal>() {
val dec = DecimalFormat("###,###,##0.0#", DecimalFormatSymbols(Locale.MYLOCALE))
override fun deserialize(parser: JsonParser, context: DeserializationContext?): BigDecimal? {
return if (parser.text != null && parser.text.isNotEmpty())
dec.parse(parser.text).toString().toBigDecimal()
else null
}
}
with
@field:JsonDeserialize(using = BigDecimalCustomDeserializer::class)
val amount: BigDecimal,